package com.quanyan.club.service.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.quanyan.activity.entity.ActivityInfo;
import com.quanyan.activity.response.RespActivityPoster;
import com.quanyan.activity.service.ActivityOpenService;
import com.quanyan.api.APIRequest;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.assets.response.RespRuleDetail;
import com.quanyan.club.constants.ClubConstants;
import com.quanyan.club.entity.RespClubMember;
import com.quanyan.club.entity.RespClubXpLevelMsg;
import com.quanyan.club.entity.RespShareUrl;
import com.quanyan.club.entity.db.*;
import com.quanyan.club.entity.vo.msg.ActivityRelatedMsg;
import com.quanyan.club.entity.vo.req.*;
import com.quanyan.club.entity.vo.resp.*;
import com.quanyan.club.mapper.*;
import com.quanyan.club.mq.producer.ClubXpLevelProducer;
import com.quanyan.club.service.*;
import com.quanyan.club.sms.ClubSmsService;
import com.quanyan.club.task.TimerTaskJob;
import com.quanyan.club.util.ActivityUtils;
import com.quanyan.club.util.NumberGenerator;
import com.quanyan.comment.constants.UserCenterConstants;
import com.quanyan.comment.enums.TaskEnum;
import com.quanyan.comment.reqeust.ReqUserCollect;
import com.quanyan.comment.reqeust.ReqUserCollectQuery;
import com.quanyan.comment.response.RespUserCollect;
import com.quanyan.comment.serviceFacade.CommentServiceFacade;
import com.quanyan.comment.serviceFacade.UserCollectServiceFacade;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.constants.MqConstants;
import com.quanyan.common.enums.BaseEnum;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.*;
import com.quanyan.mq.client.QcMsgClient;
import com.quanyan.mq.client.reqeust.MqRequestMsg;
import com.quanyan.orderpay.request.*;
import com.quanyan.orderpay.response.RespPayInfo;
import com.quanyan.orderpay.response.RespPreOrder;
import com.quanyan.orderpay.response.mq.OrderCallBackMsg;
import com.quanyan.orderpay.response.mq.OrderNotifyMsg;
import com.quanyan.orderpay.response.mq.RefundNotifyMsg;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.pay.enums.PayWayEnum;
import com.quanyan.pay.enums.RefundStatusEnum;
import com.quanyan.place.client.PlaceClient;
import com.quanyan.place.entity.PlaceDubboProvider;
import com.quanyan.redisCluster.config.RedisTemplate;
import com.quanyan.redisCluster.utils.RedisConstants;
import com.quanyan.redisCluster.utils.RedisKey;
import com.quanyan.search.entity.request.ReqActivitySearchInfo;
import com.quanyan.search.entity.response.ActivitySearchResponse;
import com.quanyan.search.entity.response.SearchResponses;
import com.quanyan.search.service.ActivitySearchService;
import com.quanyan.search.service.impl.ActivitySearchServiceImpl;
import com.quanyan.user.mq.UserTaskMsg;
import com.quanyan.user.response.RespOpenUserInterest;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.response.RespUserInfoDetail;
import com.quanyan.user.serviceFacade.UserServiceFacade;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author Li Shuai
 * @date 16/5/27
 */
@Service("clubActivityService")
public class ClubActivityServiceImpl extends BaseServiceImpl implements ClubActivityService {

    private static final Logger logger = LoggerFactory.getLogger(ClubActivityServiceImpl.class);
    private final String REGIST_ACTIVITY = "REGIST_ACTIVITY";
    private final String POST_ACTIVITY = "POST_ACTIVITY";
    private final String EVALUATION_ACTIVITY = "EVALUATION_ACTIVITY";

    @Autowired
    private TbClubActivityMapper tbClubActivityMapper;
    @Autowired
    private TbClubMapper tbClubMapper;
    @Autowired
    private ActivityOpenService activityOpenService;
    @Autowired
    private TbOrderMapper orderMapper;
    @Autowired
    private TbOrderRefundMapper orderRefundMapper;
    @Autowired
    private TbSignUserMapper signUserMapper;
    @Autowired
    private ClubMemberService clubMemberService;
    @Autowired
    private TbClubOnlineMemberAccountMapper clubOnlineMemberAccountMapper;
    @Autowired
    private CommentServiceFacade commentServiceFacade;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private UserServiceFacade userServiceFacade;
    @Autowired
    private ClubActivityMapper clubActivityMapper;
    @Autowired
    private ActivityCRUDService activityCRUDService;
    @Autowired
    private UserCollectServiceFacade userCollectServiceFacade;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TbClubActivitySettlementDetailMapper settlementDetailMapper;
    @Autowired
    private TbClubActivitySettlementMapper settlementMapper;
    @Autowired
    private ClubAccountService clubAccountService;
    @Autowired
    private TimerTaskJob timerTaskJob;
    @Autowired
    private TbClubMemberMapper clubMemberMapper;
    @Autowired
    private ClubMemberMapper cumstomClubMemberMapper;
    @Autowired
    private PlaceClient placeClient;
    @Autowired
    private TbActivityPosterMapper tbActivityPosterMapper;
    @Autowired
    private ClubXpLevelProducer clubXpLevelProducer;
    @Autowired
    @Qualifier("personCenterTaskClient")
    private QcMsgClient personCenterTaskClient;
    @Autowired
    private ClubXpLevelService clubXpLevelService;
    @Autowired
    private CppService cppService;
    @Autowired
    @Qualifier("activityOrderPayRelatedClient")
    private QcMsgClient activityOrderPayRelatedClientImpl;
    @Autowired
    private ClubFinanceMgmService clubFinanceMgmService;
    @Autowired
    private TbClubOnlineMemberAccountStreamMapper clubOnlineMemberAccountStreamMapper;
    @Value("${activity_share_url}")
    private String ACTIVITY_SHARE_URL;
    @Autowired
    private ClubCommentService clubCommentService;
    @Autowired
    private ClubSmsService clubSmsService;
    @Autowired
    private ClubSearchBizService clubSearchBizService;
    @Autowired
    private ActivitySupportService activitySupportService;
    @Autowired
    private ClubIntegralService clubIntegralService;
    @Value("${android_url}")
    private String ANDROID_URL;

    @Value("${ios_url}")
    private String IOS_URL;
    @Autowired
    private TbActivityMapper tbActivityMapper;

    /**
     * 给返回协议对象赋值
     */
    private void copyProperty(RespClubActivity respClubActivity,
                              TbClubActivity tbClubActivity,
                              ActivityInfo activityInfo) {

        //活动海报
        RespActivityPoster respActivityPoster = new RespActivityPoster();
        Integer posterPicId = 0;
        if (activityInfo != null) {
            posterPicId = activityInfo.getPosterPicId();
        }
        TbActivityPoster tbActivityPoster;
        if (null != posterPicId) {
            tbActivityPoster = tbActivityPosterMapper.selectByPrimaryKey(posterPicId);
            if (null != tbActivityPoster) {
                BeanCopierUtils.copyProperties(tbActivityPoster, respActivityPoster);
            }
        }
        if (null != activityInfo) {
            BeanCopierUtils.copyProperties(activityInfo, respClubActivity);
            respClubActivity.setRespActivityPoster(respActivityPoster);
        }

        if (null != tbClubActivity) {
            BeanCopierUtils.copyProperties(tbClubActivity, respClubActivity);
            respClubActivity.setFemaleMemberFee(tbClubActivity.getFemaleMemberFee());
            respClubActivity.setIsSame(ActivityUtils.isSamePrice(tbClubActivity));
            respClubActivity.setLowestPrice(ActivityUtils.getLowestPrice(tbClubActivity));
        }
        respClubActivity.setIsSettle(tbClubActivity.getIsSettle().intValue());
        respClubActivity.setId(respClubActivity.getActivityId());
        respClubActivity.setCurTime(new Date());
        if (activityInfo != null && null == activityInfo.getPlaceId()
                && null == activityInfo.getPlaceAddress()) {
            return;
        }
        TbClub tbClub = tbClubMapper.selectByPrimaryKey(tbClubActivity.getClubId());
        respClubActivity.setClubName(tbClub.getClubName());
    }


    /**
     * 给返回协议对象赋值单个活动
     */
    private void copyPropertyForRespClubActivity(RespClubActivity respClubActivity,
                                                 TbClubActivity tbClubActivity,
                                                 ActivityInfo activityInfo, TbClub tbClub) {

        //活动海报
        RespActivityPoster respActivityPoster = new RespActivityPoster();
        Integer posterPicId = 0;
        if (activityInfo != null) {
            posterPicId = activityInfo.getPosterPicId();
        }
        TbActivityPoster tbActivityPoster;
        if (null != posterPicId) {
            tbActivityPoster = tbActivityPosterMapper.selectByPrimaryKey(posterPicId);
            if (null != tbActivityPoster) {
                BeanCopierUtils.copyProperties(tbActivityPoster, respActivityPoster);
            }
        }
        if (null != activityInfo) {
            BeanCopierUtils.copyProperties(activityInfo, respClubActivity);
            respClubActivity.setRespActivityPoster(respActivityPoster);
        }
        if (null != tbClubActivity) {
            BeanCopierUtils.copyProperties(tbClubActivity, respClubActivity);
            respClubActivity.setFemaleMemberFee(tbClubActivity.getFemaleMemberFee());
            respClubActivity.setIsSame(ActivityUtils.isSamePrice(tbClubActivity));
            respClubActivity.setLowestPrice(ActivityUtils.getLowestPrice(tbClubActivity));
        }
        if (null != tbClub) {
            respClubActivity.setClubId(tbClub.getId());
            respClubActivity.setClubName(tbClub.getClubName());
            respClubActivity.setLogoUrl(tbClub.getLogoUrl());
            respClubActivity.setJoinType(tbClub.getJoinType());
        }
        if (null != tbClubActivity.getIsSettle()) {
            respClubActivity.setIsSettle(tbClubActivity.getIsSettle().intValue());
        }
        respClubActivity.setId(respClubActivity.getActivityId());
        respClubActivity.setCurTime(new Date());
        //调场馆模块的接口 场馆
        if (null != activityInfo.getPlaceId() && activityInfo.getPlaceId() != 0) {
            try {
                Map<Integer, PlaceDubboProvider> map =
                        placeClient.getPlaceBySinglePlaceId(activityInfo.getPlaceId());
                if (null != map && null != map.get(activityInfo.getPlaceId())) {
                    PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                    if (null != map.get(activityInfo.getPlaceId())) {
                        BeanCopierUtils.copyProperties(map.get(activityInfo.getPlaceId()), placeDubboProvider);
                    }
                    respClubActivity.setPlaceDubboProvider(placeDubboProvider);
                    map.clear();
                }
            } catch (RpcException re) {
                logger.warn("调用场馆返回空值。");
            }
        } else {
            if (respClubActivity.getActivityType() != 2) {
                PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                placeDubboProvider.setName(respClubActivity.getPlaceAddress());
                placeDubboProvider.setLat(respClubActivity.getLat());
                placeDubboProvider.setLng(respClubActivity.getLng());
                respClubActivity.setPlaceDubboProvider(placeDubboProvider);
            }
        }
    }

    private Map<Integer, PlaceDubboProvider> getPlaceMap(List<Integer> placeIdList) {
        //调场馆模块的接口 场馆
        Map<Integer, PlaceDubboProvider> map = null;
        if(placeIdList == null)
        {
            return map;
        }
        try {
            map = placeClient.getPlaceListByPlaceId(placeIdList);
        } catch (RpcException re) {
            throw new BizException("调用场馆模块失败");
        }
        return map;
    }


    public APIResponse<RespShareActivity> shareClubActivityById(Integer activityId, HttpServletRequest request) {
        RespShareActivity respShareActivity = new RespShareActivity();
        //获取活动通用详情信息 调用通用接口
        ActivityInfo activityInfo = new ActivityInfo();
        try {
            activityInfo = activityOpenService.selectOneActivityById(activityId);
            if (null == activityInfo) {
                return APIResponse.returnFail("没有活动");
            }
            respShareActivity.setActivityId(activityInfo.getId());
            if (null != activityInfo.getActivityDesc()) {
                respShareActivity.setContent(activityInfo.getActivityDesc().getBodyDesc());
            }
            TbClubActivityExample example = new TbClubActivityExample();
            example.createCriteria().andActivityIdEqualTo(activityId);
            List<TbClubActivity> clubActivities = tbClubActivityMapper.selectByExample(example);
            if (null == clubActivities || clubActivities.size() == 0) {
                return APIResponse.returnFail("没有活动");
            }
            TbClubActivity tbClubActivity = clubActivities.get(0);
            if (null != tbClubActivity && null != tbClubActivity.getActivityType()) {
                respShareActivity.setActivityType(tbClubActivity.getActivityType().intValue());
            }
            respShareActivity.setStartTime(activityInfo.getStartTime().getTime());
            respShareActivity.setEndTime(activityInfo.getEndTime().getTime());
            String address = null;
            Map<Integer, PlaceDubboProvider> place = null;
            if (null != activityInfo.getPlaceAddress()) {
                respShareActivity.setAddress(activityInfo.getPlaceAddress());
            } else if (null == activityInfo.getPlaceAddress() && activityInfo.getPlaceId() > 0) {
                try {
                    place = placeClient.getPlaceBySinglePlaceId(activityInfo.getPlaceId());
                } catch (RpcException re) {
                    throw new BizException("调用场馆模块失败");
                }
                PlaceDubboProvider placeDubboProvider = place.get(activityInfo.getPlaceId());
                if (null != placeDubboProvider) {
                    respShareActivity.setAddress(placeDubboProvider.getAddress());
                }
            }
            respShareActivity.setGroupId(activityInfo.getGroupId());
            respShareActivity.setTitle(activityInfo.getName());
            //APP3.0需求 分享增加字段
            respShareActivity.setPlanner(tbClubActivity.getPlanner());
            respShareActivity.setMobile(tbClubActivity.getMobile());
            TbClub club = tbClubMapper.selectByPrimaryKey(tbClubActivity.getClubId());
            respShareActivity.setClubName(club.getClubName());
            respShareActivity.setFeeType(tbClubActivity.getFeeType().intValue());
            List<RespClubActivityMember> members = getActivityMember(null, activityId, false);
            respShareActivity.setMembers(members);
            //APP 12月底需求 展示价格
            respShareActivity.setSignUpType(tbClubActivity.getSignUpType());
            respShareActivity.setFemaleFee(tbClubActivity.getFemaleFee());
            respShareActivity.setFemaleMemberFee(tbClubActivity.getFemaleMemberFee());
            respShareActivity.setMaleFee(tbClubActivity.getMaleFee());
            respShareActivity.setMaleMemberFee(tbClubActivity.getMaleMemberFee());
            respShareActivity.setAaTotal(tbClubActivity.getAaTotal());
            respShareActivity.setAaFee(tbClubActivity.getAaFee());
            respShareActivity.setIsSame(ActivityUtils.isSamePrice(tbClubActivity));
        } catch (Exception e) {
            logger.warn(e.getMessage());
            return APIResponse.returnFail("分享失败");
        }
        //活动海报
        Integer posterPicId = activityInfo.getPosterPicId();
        if (null != posterPicId) {
            TbActivityPoster tbActivityPoster = tbActivityPosterMapper.selectByPrimaryKey(posterPicId);
            if (null != tbActivityPoster) {
                respShareActivity.setImageUrl(tbActivityPoster.getUrl());
            }
        }
        respShareActivity.setShareUrl(ACTIVITY_SHARE_URL + "?activityId=" + activityId);
        String httpResult = ShortUrlUtils.getShortUrl(respShareActivity.getShareUrl());
        String shortUrl = null;
        respShareActivity.setShortUrl(respShareActivity.getShareUrl());
        if (httpResult != null) {
            logger.warn("httpResult:" + JSONObject.toJSONString(httpResult));
            if (httpResult.contains("type")) {
                List<RespShareUrl> respShareUrls = JSON.parseArray(httpResult, RespShareUrl.class);
                if (null != respShareUrls.get(0)) {
                    respShareActivity.setShortUrl(respShareUrls.get(0).getUrl_short());
                }
            } else {
                respShareActivity.setShortUrl(respShareActivity.getShareUrl());
            }

        }
        return APIResponse.returnSuccess(respShareActivity);
    }

    /**
     * 活动详情
     */
    public APIResponse<RespClubActivity> queryClubActivityById(Integer activityId, Integer uid) {
        if (null == activityId) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        RespClubActivity respClubActivity = new RespClubActivity();
        //获取活动通用详情信息 调用通用接口
        ActivityInfo activityInfo = new ActivityInfo();
        try {
            activityInfo = getRespActivity(activityId);
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        if (null == activityInfo) {
            return APIResponse.returnFail("活动不存在");
        }
        RespActivityPoster respActivityPoster = new RespActivityPoster();
        //活动海报

        Integer posterPicId = activityInfo.getPosterPicId();
        TbActivityPoster tbActivityPoster;
        if (null != posterPicId && posterPicId != 0) {
            tbActivityPoster = tbActivityPosterMapper.selectByPrimaryKey(posterPicId);

        } else {
            tbActivityPoster = new TbActivityPoster();
        }
        BeanCopierUtils.copyProperties(tbActivityPoster, respActivityPoster);
        respClubActivity.setRespActivityPoster(respActivityPoster);

        //俱乐部活动扩展信息
        TbClubActivityExample example = new TbClubActivityExample();
        example.createCriteria().andActivityIdEqualTo(activityId);
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(tbClubActivityList)) {
            return APIResponse.returnFail("活动不存在");
        }
        TbClubActivity tbClubActivity = tbClubActivityList.get(0);
        //俱乐部信息
        TbClub tbClub = tbClubMapper.selectByPrimaryKey(tbClubActivity.getClubId());
        if (null != uid) {
            //当前用户在俱乐部的权限信息
            TbClubMemberExample memberExample = new TbClubMemberExample();
            memberExample.createCriteria().andUidEqualTo(uid)
                    .andClubIdEqualTo(tbClub.getId()).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
            List<TbClubMember> clubMembers = clubMemberMapper.selectByExample(memberExample);
            if (clubMembers != null && clubMembers.size() > 0) {
                respClubActivity.setIsClubMember(1);//俱乐部成员
                respClubActivity.setRoleCode(clubMembers.get(0).getRoleCode());
            }
        }
        isActivityAlreadyCollect(activityId, uid, activityInfo, tbClubActivity, tbClub, respClubActivity);
        boolean isAdmin = false;
        if (null != uid) {
            isAdmin = clubMemberService.isClubAdminMember(uid, tbClub.getId());
        }
        logger.warn("开始获取报名成员");
        List<RespClubActivityMember> respClubActivityMembers = getActivityMember(uid, activityId, isAdmin);
        respClubActivity.setSignUserList(respClubActivityMembers);
        //APP3.0需求 活动详情展示最近一条活动评价
        logger.warn("开始获取活动评价");
        ReqClubCommentPage reqClubCommentPage = new ReqClubCommentPage();
        reqClubCommentPage.setPageNum(0);
        reqClubCommentPage.setPageSize(1);
        reqClubCommentPage.setClubId(tbClub.getId());
        reqClubCommentPage.setActivityId(activityId);
        PageObj<List<RespClubComment>> commentList =
                clubCommentService.getClubCommentList(reqClubCommentPage);
        if(null != commentList)
        {
            List<RespClubComment> comments = commentList.getItems();
            if (null != comments && comments.size() == 1) {
                respClubActivity.setLastComment(comments.get(0));
            }
        }
        return APIResponse.returnSuccess(respClubActivity);
    }

    /**
     * 活动详情(简要)
     */
    public APIResponse<RespClubActivity> queryClubActivityById(Integer activityId) {
        if (null == activityId) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        RespClubActivity respClubActivity = new RespClubActivity();
        //获取活动通用详情信息 调用通用接口
        ActivityInfo activityInfo = new ActivityInfo();
        try {
            activityInfo = activityOpenService.selectOneActivityById(activityId);
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        if (null == activityInfo) {
            return APIResponse.returnFail("活动不存在");
        }
        //俱乐部活动扩展信息
        TbClubActivityExample example = new TbClubActivityExample();
        example.createCriteria().andActivityIdEqualTo(activityId);
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(tbClubActivityList)) {
            return APIResponse.returnFail("活动不存在");
        }
        TbClubActivity tbClubActivity = tbClubActivityList.get(0);
        TbClub club = tbClubMapper.selectByPrimaryKey(tbClubActivity.getClubId());
        copyPropertyForRespClubActivity(respClubActivity, tbClubActivity, activityInfo, club);
        return APIResponse.returnSuccess(respClubActivity);
    }

    public void isActivityAlreadyCollect(Integer activityId, Integer uid, ActivityInfo activityInfo,
                                         TbClubActivity tbClubActivity,
                                         TbClub tbClub, RespClubActivity respClubActivity) {
        if (uid != null) {
            ReqUserCollectQuery reqUserCollect = new ReqUserCollectQuery();
            reqUserCollect.setSystemCode(UserCenterConstants.SystemCode.SYSTEM_ACTIVITY);
            reqUserCollect.setBusinessCode(UserCenterConstants.BusinessCode.BUSINESS_CLUB_ACTIVITY_COLLECT);
            reqUserCollect.setUserId(uid);
            reqUserCollect.setBusinessId(activityId);
            APIResponse<Boolean> apiResponse = userCollectServiceFacade.isUserCollect(reqUserCollect);
            Boolean flag = apiResponse.getData();//false 未收藏 true收藏
            if (!flag) {
                respClubActivity.setIsCollect((byte) 1);//是否收藏 0 未收藏 1 已收藏
            } else {
                respClubActivity.setIsCollect((byte) 0);//是否收藏 0 未收藏 1 已收藏
            }
        }
        copyPropertyForRespClubActivity(respClubActivity, tbClubActivity, activityInfo, tbClub);
    }

    /**
     * 调solr
     */
    public APIResponse<PageObj<List<RespSearchActivity>>> queryActivityListByCondition(ReqClubActivitySearch reqActivitySearch) {
        if (null != reqActivitySearch.getCurrentUserId() && reqActivitySearch.getCurrentUserId() > 0) {
            if (reqActivitySearch.getName() != null && !"".equals(reqActivitySearch)) {
                List<Integer> clubIdList =
                        cumstomClubMemberMapper.selectClubIdByUid(reqActivitySearch.getCurrentUserId());
                logger.warn("=========用户UID：" + reqActivitySearch.getCurrentUserId()
                        + "关联的俱乐部ID:" + JSONObject.toJSONString(clubIdList));
                reqActivitySearch.setClubIds(clubIdList);
            }
        }
        logger.warn("首页活动列表开始时间：" + DateTimeUtils.getCurrentDate().getTime());
        logger.debug("===================搜索条件===========reqSearchVo: {}", JSON.toJSONString(reqActivitySearch));
        ReqActivitySearchInfo reqActivitySearchInfo = getReqActivitySearchInfo(reqActivitySearch);
        logger.debug("===================转换搜索对象===========ReqPlaceSearchInfo:{}",
                JSON.toJSONString(reqActivitySearchInfo));
        if (StringUtils.isEmpty(reqActivitySearch.getPageNum()) || reqActivitySearch.getPageNum() == Constants.DEFAULT_PAGE_NUM) {
            reqActivitySearch.setPageNum(Constants.DEFAULT_PAGE_NUM);
        }
        APIResponse<SearchResponses<List<ActivitySearchResponse>>> response = listSearch(reqActivitySearchInfo);
        logger.debug("===================调用搜索引擎===========APIResponse<List<PlaceSearchResponse>>:{},调用solr开始时间" + DateTimeUtils.getCurrentDate().getTime(),
                JSON.toJSONString(response));

        if (!response.isRet()) {
            logger.error("===================调用搜索引擎失败===========ReqPlaceSearchInfo:{}",
                    JSON.toJSONString(reqActivitySearchInfo));
            return APIResponse.returnFail("没有记录");
        }
        logger.warn("调用solr返回结果时间：" + DateTimeUtils.getCurrentDate().getTime());
        List<ActivitySearchResponse> list = response.getData().getData();
        if (null == list || list.size() == 0) {
            logger.warn("===================调用搜索引擎查询无结果===========ReqPlaceSearchInfo:{}",
                    JSON.toJSONString(reqActivitySearchInfo));
            List<RespSearchActivity> resp = new ArrayList<RespSearchActivity>();
            PageObj<List<RespSearchActivity>> pageObj = PageObj.create(0, reqActivitySearch.getPageNum(),
                    reqActivitySearch.getPageSize(), resp);
            return APIResponse.returnSuccess(pageObj);
        }
        //组装对象
        List<RespSearchActivity> searchActivityList =
                activitySupportService.searchActivityWithPlaceInfo(list, reqActivitySearch.getClubIds(),
                        reqActivitySearch.getRemoveActivityIds());
        if (null == searchActivityList) {
            searchActivityList = new ArrayList<RespSearchActivity>();
        }
        Integer total = response.getData().getTotal();
        PageObj<List<RespSearchActivity>> pageObj = PageObj.create(total, reqActivitySearch.getPageNum(),
                reqActivitySearch.getPageSize(), searchActivityList);
        return APIResponse.returnSuccess(pageObj);
    }


    @Override
    public APIResponse<RespMyDetailSearchActivity> queryMyDetailActivityListByCondition(
            ReqClubActivitySearch reqActivitySearch, Integer uid) {
        List<Integer> clubIdList = cumstomClubMemberMapper.selectClubIdByUid(uid);
        List<Integer> myAllActivityIds = null;
        logger.warn("=========用户UID：" + uid + "关联的俱乐部ID:" + JSONObject.toJSONString(clubIdList));
        List<RespSearchActivity> myAllActivities = new ArrayList<RespSearchActivity>();
        RespMyDetailSearchActivity respMyDetailSearchActivity = new RespMyDetailSearchActivity();
        //获取我的俱乐部ID并放进搜索请求中
        if (CollectionUtils.isNotEmpty(clubIdList)) {
            reqActivitySearch.setClubIds(clubIdList);
            myAllActivityIds = clubActivityMapper.selectEffectiveActivityByClubIds(
                    clubIdList, DateUtils.getTimesmorning(), DateUtils.getTimesnight(),
                    reqActivitySearch.getCityId(), reqActivitySearch.getDistrictId(),
                    reqActivitySearch.getCategoryId());
            logger.warn("============用户UID：" + uid +
                    "今天的活动：" + JSONObject.toJSONString(myAllActivityIds));
            if (CollectionUtils.isNotEmpty(myAllActivityIds)) {
                for (Integer activityId : myAllActivityIds) {
                    APIResponse<RespClubActivity> resp = queryClubActivityById(activityId);
                    if (!resp.isRet()) {
                        logger.warn("activityId:" + activityId + "没有查到。" + resp.getErrmsg());
                        continue;
                    }
                    RespClubActivity clubActivity = resp.getData();
                    Map<Integer, String> categoryMap = activitySupportService.getCategoryMap();
                    RespSearchActivity respSearchActivity =
                            dbActivityToSearch(categoryMap, clubActivity, reqActivitySearch.getLat(), reqActivitySearch.getLng());
                    myAllActivities.add(respSearchActivity);
                }
                logger.warn("调测日志：" + JSONObject.toJSONString(myAllActivities));
                logger.warn("调测日志：" + JSONObject.toJSONString(myAllActivityIds));
                reqActivitySearch.setRemoveActivityIds(myAllActivityIds);
            }
        }
        respMyDetailSearchActivity.setMyAllActivitys(myAllActivities);
        logger.debug("==================queryMyDetailActivityListByCondition调用queryActivityListByCondition开始时间：" + DateTimeUtils.getCurrentDate().getTime());
        APIResponse<PageObj<List<RespSearchActivity>>> ret = queryActivityListByCondition(reqActivitySearch);
        logger.debug("==================queryMyDetailActivityListByCondition调用queryActivityListByCondition结束时间：" + DateTimeUtils.getCurrentDate().getTime());
        if (true == ret.isRet()) {
            logger.debug("==================queryMyDetailActivityListByCondition调用queryActivityListByCondition成功");
            respMyDetailSearchActivity.setPageObj(ret.getData());
        } else {
            logger.warn("===================queryMyDetailActivityListByCondition调用queryActivityListByCondition失败");
            List<RespSearchActivity> resp = new ArrayList<RespSearchActivity>();
            PageObj<List<RespSearchActivity>> pageObj = PageObj.create(0, reqActivitySearch.getPageNum(),
                    reqActivitySearch.getPageSize(), resp);
            respMyDetailSearchActivity.setPageObj(pageObj);
        }
        return APIResponse.returnSuccess(respMyDetailSearchActivity);
    }

    private RespSearchActivity dbActivityToSearch(Map<Integer, String> categoryMap, RespClubActivity clubActivity, Double lat, Double lng) {
        RespSearchActivity respSearchActivity = new RespSearchActivity();

        respSearchActivity.setActivityId(String.valueOf(clubActivity.getActivityId()));
        respSearchActivity.setLat(clubActivity.getLat());
        respSearchActivity.setLng(clubActivity.getLng());
        respSearchActivity.setCategoryId(clubActivity.getCategoryId());
        if(categoryMap.containsKey(clubActivity.getCategoryId()))
        {
            respSearchActivity.setCategoryName(categoryMap.get(clubActivity.getCategoryId()));
        }
        if(StringUtils.isEmpty(respSearchActivity.getCategoryName()))
        {
            respSearchActivity.setCategoryName("其他");
        }
        //活动海报
        RespActivityPoster poster = clubActivity.getRespActivityPoster();
        if (null != poster) {
            respSearchActivity.setActivityUrl(poster.getUrl());
        }
        respSearchActivity.setActivityName(clubActivity.getName());
        respSearchActivity.setAlreadySignTotalNum(clubActivity.getAlreadySignTotalNum());
        respSearchActivity.setLimitNum(clubActivity.getLimitNum());
        respSearchActivity.setActivityType(clubActivity.getActivityType());
        respSearchActivity.setActivityEndTime(clubActivity.getEndTime());
        respSearchActivity.setActivityStartTime(clubActivity.getStartTime());
        respSearchActivity.setActivityClubName(clubActivity.getClubName());
        respSearchActivity.setNowServerTime(new Date());
        TbClub club = tbClubMapper.selectByPrimaryKey(clubActivity.getClubId());
        respSearchActivity.setClubLogo(club.getLogoUrl());
        respSearchActivity.setLogoUrl(club.getLogoUrl());
        if (null != clubActivity.getLowestPrice()) {
            respSearchActivity.setActivityPrice(clubActivity.getLowestPrice().doubleValue());
        }
        if (clubActivity.getLimitNum() > 0) {
            if (clubActivity.getLimitNum().equals(clubActivity.getAlreadySignTotalNum())) {
                respSearchActivity.setActivityIsFull(1);
            }
        }
        if (System.currentTimeMillis() - clubActivity.getSignEndTime().getTime() >= 0) {
            respSearchActivity.setActivityIsDeadline(1);
        }
        //无场馆活动
        if (clubActivity.getPlaceId() == 0) {
            String address = clubActivity.getPlaceAddress();
            respSearchActivity.setActivitySite(address);
            respSearchActivity.setPlaceAddress(address);
        }
        //有场馆活动
        else if (null != clubActivity.getPlaceDubboProvider()) {
            PlaceDubboProvider placeDubboProvider = clubActivity.getPlaceDubboProvider();
            respSearchActivity.setPlaceDubboProvider(placeDubboProvider);
            respSearchActivity.setActivitySite(placeDubboProvider.getName());
            respSearchActivity.setLat(placeDubboProvider.getLat());
            respSearchActivity.setLng(placeDubboProvider.getLng());
        }
        //计算距离
        double latActivity = clubActivity.getLat();
        double lngActivity = clubActivity.getLng();
        Double activityDist = DistanceUtil.getDistanceRice(lngActivity, latActivity, lng, lat);
        respSearchActivity.setActivityDist(activityDist.floatValue());
        respSearchActivity.setIsMine(1);
        return respSearchActivity;
    }

    public ReqActivitySearchInfo getReqActivitySearchInfo(ReqClubActivitySearch reqClubActivitySearch) {
        Integer pageNum = reqClubActivitySearch.getPageNum();
        Integer pageSize = reqClubActivitySearch.getPageSize();
        ReqActivitySearchInfo reqActivitySearchInfo = new ReqActivitySearchInfo();
        //APP3.0需求 按名字平台搜索活动功能
        if (null != reqClubActivitySearch.getName()) {
            String name = reqClubActivitySearch.getName().toLowerCase();
            reqActivitySearchInfo.setName(name);
            reqActivitySearchInfo.setType(ActivityUtils.getStringType(name));
            if (null == reqClubActivitySearch.getLat()) {
                reqClubActivitySearch.setLat(0.0);
            }
            reqActivitySearchInfo.setLat(reqClubActivitySearch.getLat());
            if (null == reqClubActivitySearch.getLng()) {
                reqClubActivitySearch.setLng(0.0);
            }
            reqActivitySearchInfo.setLng(reqClubActivitySearch.getLng());
            reqActivitySearchInfo.setPageNo(pageNum);//solr搜索接口要求从0开始第一页
            reqActivitySearchInfo.setPageSize(pageSize);
            logger.warn("请求搜索引擎入参:" + JSON.toJSONString(reqActivitySearchInfo));
            return reqActivitySearchInfo;
        }
        reqActivitySearchInfo.setCategoryId(reqClubActivitySearch.getCategoryId());
        if(null != reqClubActivitySearch.getCityId() && reqClubActivitySearch.getCityId() > 0)
        {
            reqActivitySearchInfo.setCityId(reqClubActivitySearch.getCityId());
        }
        if(null != reqClubActivitySearch.getDistrictId() && reqClubActivitySearch.getDistrictId() > 0)
        {
            reqActivitySearchInfo.setDistrictId(reqClubActivitySearch.getDistrictId());
        }
        reqActivitySearchInfo.setLat(reqClubActivitySearch.getLat() == null ? 0.00 : reqClubActivitySearch.getLat());
        reqActivitySearchInfo.setLng(reqClubActivitySearch.getLng() == null ? 0.00 : reqClubActivitySearch.getLng());
        reqActivitySearchInfo.setSortId(reqClubActivitySearch.getSortId());
        if (null != reqClubActivitySearch.getTime() && reqClubActivitySearch.getTime() > 0) {
            reqActivitySearchInfo.setDateParam(reqClubActivitySearch.getTime());
        }
        reqActivitySearchInfo.setDistance(reqClubActivitySearch.getDistance());
        reqActivitySearchInfo.setPageNo(pageNum);//solr搜索接口要求从0开始第一页
        reqActivitySearchInfo.setPageSize(pageSize);
        reqActivitySearchInfo.setCategories(reqClubActivitySearch.getCategories());
        logger.warn("请求搜索引擎入参:" + JSON.toJSONString(reqActivitySearchInfo));
        return reqActivitySearchInfo;
    }

    public APIResponse<SearchResponses<List<ActivitySearchResponse>>> listSearch(ReqActivitySearchInfo reqActivitySearchInfo) {
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        return activitySearchService.searchActivityInfoListNew(reqActivitySearchInfo);
    }

    //根据俱乐部活动列表获取活动列表信息
    public List<ActivityInfo> getActivityInfoList(List<Integer> activityIdList) {
        List<ActivityInfo> activityInfoList = new ArrayList<ActivityInfo>();
        try {
            activityInfoList = activityOpenService.queryActivityList(activityIdList);
        } catch (RpcException re) {
            logger.warn(re.getMessage());
            throw new BizException("调用活动模块异常");
        }

        return activityInfoList;
    }

    /**
     * 收藏活动
     */
    public APIResponse collect(@NotNull(message = "uid不能为空") Integer uid, @NotNull(message = "activityId不能为空") Integer activityId,
                               @NotNull(message = "type不能为空") Integer type) {
        ReqUserCollect reqUserCollect = new ReqUserCollect();
        reqUserCollect.setSystemCode(UserCenterConstants.SystemCode.SYSTEM_ACTIVITY);
        reqUserCollect.setBusinessCode(UserCenterConstants.BusinessCode.BUSINESS_CLUB_ACTIVITY_COLLECT);
        reqUserCollect.setUserId(uid);
        reqUserCollect.setBusinessId(activityId);
        reqUserCollect.setStatus(type);

        APIResponse<?> apiResponse;
        if (type.intValue() == Constants.YES) {
            apiResponse = userCollectServiceFacade.userCollect(reqUserCollect);
        } else {
            apiResponse = userCollectServiceFacade.cancleUserCollect(reqUserCollect);
        }
        if (!apiResponse.isRet()) {
            return APIResponse.returnFail("调用收藏服务失败");
        }
        APIResponse<Integer> response = new APIResponse<>();
        BeanCopierUtils.copyProperties(apiResponse, response);
        if (apiResponse.getErrcode() == ApiResponseEnum.SUCCESS.getId()) {
            response.setData(Integer.parseInt(Constants.YES + ""));
            // 增加/取消收藏活动放redis
            RedisKey rediskey = new RedisKey(RedisConstants.ACTIIVTY_FORWARD_CACHE_PREFIX, uid + ClubConstants.USER_ACTIVITY_COLLECT_REDIS_KEY);
            RespClubActivity respClubActivity = queryClubActivityById(activityId, uid).getData();
            if (!StringUtils.isEmpty(respClubActivity)) {
                if (type.intValue() == Constants.YES) {
                    this.redisTemplate.hset(rediskey.getRedisKey(), activityId + "", respClubActivity);
                } else {
                    this.redisTemplate.hdel(rediskey.getRedisKey(), activityId.toString().getBytes());
                }
            }
        } else {
            response.setData(Integer.parseInt(Constants.NO + ""));
        }
        return response;
    }

    /**
     * 收藏活动列表
     */
    public APIResponse<PageObj<List<RespClubActivity>>> queryActivityListCollect(Integer uid, Integer pageIndex, Integer pageSize) {
        RedisKey rediskey = new RedisKey(RedisConstants.ACTIIVTY_FORWARD_CACHE_PREFIX, uid + ClubConstants.USER_ACTIVITY_COLLECT_REDIS_KEY);
        List<Object> redisRespObjectList = (List<Object>) this.redisTemplate.hvals(rediskey.getRedisKey());
        APIResponse response = new APIResponse();
        List<RespClubActivity> redisRespClubActivityList = new ArrayList<RespClubActivity>();
        // 判断redis中是否有收藏数据
        if (null == redisRespObjectList || redisRespObjectList.size() == 0) {//没有数据
            ReqUserCollectQuery reqUserCollectQuery = new ReqUserCollectQuery();
            reqUserCollectQuery.setSystemCode(UserCenterConstants.SystemCode.SYSTEM_ACTIVITY);
            reqUserCollectQuery.setBusinessCode(UserCenterConstants.BusinessCode.BUSINESS_CLUB_ACTIVITY_COLLECT);
            reqUserCollectQuery.setUserId(uid);
            reqUserCollectQuery.setPageNum(pageIndex);
            reqUserCollectQuery.setPageSize(pageSize);
            APIResponse<PageObj<List<RespUserCollect>>> apiResponse = userCollectServiceFacade.queryUserCollect(reqUserCollectQuery);
            if (!apiResponse.isRet()) {
                return APIResponse.returnFail("调用收藏列表服务失败");
            }
            PageObj<List<RespUserCollect>> datas1 = apiResponse.getData();
            if (StringUtils.isEmpty(datas1) && CollectionUtils.isEmpty(datas1.getItems())) {
                response.setData(null);
                return response;
            }
            List<RespUserCollect> datas = datas1.getItems();
            try {
                for (int i = 0, len = datas.size(); i < len; i++) {
                    RespUserCollect reqUserCollect = datas.get(i);
                    Integer activityId = Integer.parseInt(reqUserCollect.getBusinessId());
                    APIResponse<RespClubActivity> apiresponse = queryClubActivityById(activityId);
                    if (!StringUtils.isEmpty(apiresponse)) {
                        redisRespClubActivityList.add(apiresponse.getData());
                    }
                    this.redisTemplate.hset(rediskey.getRedisKey(), activityId + "", apiresponse);
                }
                PageObj<List<RespClubActivity>> pageObj = PageObj.create(datas1.getTotal(), pageIndex, pageSize, redisRespClubActivityList);
                return APIResponse.returnSuccess(pageObj);
            } catch (Exception e) {
                logger.error("活动收藏列表:用户ID：{}失败:{}", uid, e);
                return APIResponse.returnFail("活动收藏列表失败");
            }
        }
        for (Object obj : redisRespObjectList) {
            RespClubActivity respClubActivity = (RespClubActivity) obj;
            redisRespClubActivityList.add(respClubActivity);
        }
        PageModel pageModel = new PageModel(redisRespClubActivityList, pageSize);
        List<RespClubActivity> list = pageModel.getObjects(pageIndex);
        PageObj<List<RespClubActivity>> pageObj = PageObj.create(redisRespClubActivityList.size(), pageIndex, pageSize, list);

        return APIResponse.returnSuccess(pageObj);
    }

    /**
     * 获取活动通用详情信息 调用活动接口
     */
    public ActivityInfo getRespActivity(Integer activityId) {
        ActivityInfo activityInfo = activityOpenService.queryOneActivityById(activityId);
        return activityInfo;
    }

    public List<RespClubActivity> batchQueryActivityList(List<Integer> activityIdList) {
        TbClubActivityExample example = new TbClubActivityExample();
        if (CollectionUtils.isNotEmpty(activityIdList)) {
            example.createCriteria().andActivityIdIn(activityIdList);
        }
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(example);
        List<ActivityInfo> activityInfoList = activityOpenService.queryActivityList(activityIdList);
        //组合活动对象(主体+扩展)
        List<RespClubActivity> respClubActivityList = new ArrayList<>();
        RespClubActivity respClubActivity = null;
        if (CollectionUtils.isNotEmpty(tbClubActivityList)) {
            for (TbClubActivity tbClubActivity : tbClubActivityList) {
                for (ActivityInfo activityInfo : activityInfoList) {
                    respClubActivity = new RespClubActivity();
                    if (tbClubActivity.getActivityId().equals(activityInfo.getId())) {
                        copyProperty(respClubActivity, tbClubActivity, activityInfo);
                        activitySupportService.isClubTask(respClubActivity);
                        respClubActivityList.add(respClubActivity);
                    }
                }
            }
        }
        return respClubActivityList;
    }


    /**
     * 活动预支付下单
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse<ResPrePaymentOrderInfo> activityPrePaymentOrder(ReqSignUpInfo reqSignUpInfo,
                                                                       Integer currentUserId, HttpServletRequest request) {

        //活动条件校验
        APIResponse<RespClubActivity> clubActivityAPIResponse = validatedUserSignUp(reqSignUpInfo);
        if (!clubActivityAPIResponse.isRet()) {
            return APIResponse.returnFail(
                    clubActivityAPIResponse.getErrcode(), clubActivityAPIResponse.getErrmsg());
        }
        //获取个人俱乐部余额
        RespClubActivity respClubActivity = clubActivityAPIResponse.getData();

        //活动报名人数校验
        APIResponse signUpNumLimitResponse =
                validatedActivitySignUpNumLimit(reqSignUpInfo, respClubActivity);
        if (!signUpNumLimitResponse.isRet()) {
            return signUpNumLimitResponse;
        }

        TbClubOnlineMemberAccount clubOnlineMemberAccount =
                clubAccountService.queryClubMemberAccount(
                        respClubActivity.getClubId(), currentUserId);

        BigDecimal clubPersonMoney = null;
        if (clubOnlineMemberAccount != null) {
            clubPersonMoney = clubOnlineMemberAccount.getMoneyTotal();
        }

        //获取个人鸟蛋
        RespRuleDetail respRuleDetail = clubAccountService.getPersonEggsInfo(
                currentUserId, reqSignUpInfo.getDealAmount());
        Long accumulate = null;
        BigDecimal exchangeRMB = null;
        if (respRuleDetail != null) {
            String appVersion = reqSignUpInfo.getVer();
            logger.warn("------------------ver=" + appVersion);
            if (!StringUtil.isBlankOrNull(appVersion) && appVersion.startsWith("2.0")) {
                accumulate = respRuleDetail.getUseAccumulate();
                exchangeRMB = respRuleDetail.getExchangeRMB();
            } else {
                accumulate = respRuleDetail.getAccount().getAccumulate(); //获取个人鸟蛋，可用鸟蛋由前端计算
                if (accumulate != null) {
                    exchangeRMB = new BigDecimal(accumulate).divide(new BigDecimal(10), 2, RoundingMode.HALF_UP);
                }
            }
        }

        //获取支付方式
        List<RespPayInfo> respPayInfoList =
                clubAccountService.getSysPayInfo(Constants.CLUB_ACTIVITY_ORDER_BUSINESS_CODE);
        if (CollectionUtils.isEmpty(respPayInfoList)) {
            return APIResponse.returnFail("获取支付方式失败");
        }

        ResPrePaymentOrderInfo resPrePaymentOrderInfo = new ResPrePaymentOrderInfo();
//        resPrePaymentOrderInfo.setOrderTime(orderTime.getTime());
        resPrePaymentOrderInfo.setRespPayInfoList(respPayInfoList);
//        resPrePaymentOrderInfo.setBusinessOrderNo(businessOrderNo);

//        if (reqSignUpInfo.getCoupon() == null){
//            return APIResponse.returnFail("缺少获取优惠券参数！");
//        }
//        if (reqSignUpInfo.getCoupon().getSportType() == null){
//            return APIResponse.returnFail("缺少优惠券运动类型参数！");
//        }
//        ReqCoupon reqCoupon = new ReqCoupon();
//        reqCoupon.setUid(currentUserId);
//        reqCoupon.setSportType(reqSignUpInfo.getCoupon().getSportType());
//        reqCoupon.setOrderType(CouponOrderType.CLUB_ACTIVITY.id.byteValue());
//        reqCoupon.setEnabledAmount(reqSignUpInfo.getDealAmount());
//        APIRequest<ReqCoupon> request = new APIRequest<>();
//        request.setData(reqCoupon);
//        logger.warn("coupon request=" + JSON.toJSONString(request));
//        APIResponse<RespOrderCoupon> response =  couponService.getOrderCouponList(request);
//        if (response == null || !response.isRet()){
//            return APIResponse.returnFail("获取优惠券信息失败！");
//        }
//        resPrePaymentOrderInfo.setOrderCoupon(response.getData());

        resPrePaymentOrderInfo.setClubPersonMoney(
                clubPersonMoney == null ? new BigDecimal(0) : clubPersonMoney);

        resPrePaymentOrderInfo.setAccumulate(accumulate == null ? 0 : accumulate);

        resPrePaymentOrderInfo.setExchangeRMB(
                exchangeRMB == null ? new BigDecimal(0) : exchangeRMB);

        return APIResponse.returnSuccess(resPrePaymentOrderInfo);
    }

    /**
     * 校验活动人数限制
     */
    private APIResponse validatedActivitySignUpNumLimit(ReqSignUpInfo reqSignUpInfo,
                                                        RespClubActivity respClubActivity) {

        List<ActivitySignMemberInfo> activitySignMemberInfoList
                = reqSignUpInfo.getActivitySignMemberInfoList();
        if (CollectionUtils.isEmpty(activitySignMemberInfoList)) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }

        logger.warn("respClubActivity.getLimitNum(): " + respClubActivity.getLimitNum());

        if (respClubActivity.getLimitNum() > 0
                && activitySignMemberInfoList.size() > respClubActivity.getLimitNum()) {
            logger.warn("activitySignMemberInfoList" + activitySignMemberInfoList.size());
            return APIResponse.returnFail("活动报名人数超过规定限制");
        }

        int signUpManNum = 0; //此次报名男生人数
        int signUpWomenNum = 0;//此次报名女生人数
        for (ActivitySignMemberInfo member : activitySignMemberInfoList) {
            if (null != member) {
                signUpManNum++;
            }
        }
        if (respClubActivity.getLimitNum() != null && respClubActivity.getLimitNum() > 0) {
            if ((respClubActivity.getAlreadySignTotalNum() + signUpManNum)
                    > respClubActivity.getLimitNum()) {
                logger.warn("getAlreadySignTotalNum" + (respClubActivity.getAlreadySignTotalNum() + signUpManNum));
                return APIResponse.returnFail("报名人数超过活动规定限制");
            }
        }
        return APIResponse.returnSuccess();
    }

    /**
     * 活动报名
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse<RespPreOrder> activitySignUp(ReqSignUpDetail reqSignUpInfo,
                                                    Integer currentUserId, String requestIp,
                                                    String appVersion,
                                                    HttpServletRequest request) {
        //活动条件校验
        APIResponse<RespClubActivity> clubActivityAPIResponse = validatedUserSignUp(reqSignUpInfo);
        if (!clubActivityAPIResponse.isRet()) {
            return APIResponse.returnFail(
                    clubActivityAPIResponse.getErrcode(), clubActivityAPIResponse.getErrmsg());
        }
        RespClubActivity respClubActivity = clubActivityAPIResponse.getData();
        ActivitySignMemberInfo mainMemberInfo = null;
        for (ActivitySignMemberInfo signMemberInfo :
                reqSignUpInfo.getActivitySignMemberInfoList()) {
            if (signMemberInfo.getSignUpType().intValue() == 0) {
                mainMemberInfo = signMemberInfo;
                break;
            }
        }
        APIResponse validateSignUpFeeRes = validateSignUpFee(reqSignUpInfo, respClubActivity, currentUserId);
        if (!validateSignUpFeeRes.isRet()) {
            return validateSignUpFeeRes;
        }
        //下单时间
        Date orderTime = new Date();
        //业务系统单号
        String businessOrderNo = CommonUtils.generateBusinessOrderNo(
                Constants.CLUB_SYSTEM, currentUserId);

        //调用订单系统生成订单
        logger.warn("开始调用订单系统生成订单");
        APIResponse<RespPreOrder> preOrderAPIResponse = this.invokeRpcBuildClubActivityOrder(
                reqSignUpInfo, mainMemberInfo, respClubActivity,
                requestIp, request, businessOrderNo, appVersion);
        if (!preOrderAPIResponse.isRet()) {
            logger.error("调用订单系统生成订单失败 , 失败信息: " + preOrderAPIResponse.getErrmsg());
            if (preOrderAPIResponse.getErrcode() == 21012) {
                throw new BizException("当前支付方式不可用，请使用其他支付方式或稍后再试。");
            }
            throw new BizException("订单生成失败," + preOrderAPIResponse.getErrmsg());
        }
        logger.warn("调用订单系统生成订单结束");
        RedisKey rediskey = new RedisKey(RedisConstants.ACTIIVTY_FORWARD_CACHE_PREFIX,
                currentUserId + businessOrderNo + ClubConstants.USER_ACTIVITY_ORDER_PAY_RES_INFO);

        Integer memberAccountStreamStatus = 2; //0:待处理 1：处理成功 2处理中 3：处理失败
        if (reqSignUpInfo.getPayAmount() != null
                && reqSignUpInfo.getPayAmount().doubleValue() > 0) {
            //不是零元订单, 需要用户调用第三方支付金额, 缓存支付信息10分钟
            redisTemplate.setWithExpireTime(rediskey, preOrderAPIResponse, 10 * 60);
        } else {
            memberAccountStreamStatus = 1;
        }

        //如果有俱乐部余额抵扣, 则扣除相应的账户余额
        if (reqSignUpInfo.getBalanceAmount() != null
                && reqSignUpInfo.getBalanceAmount().doubleValue() > 0) {
            ClubMemberAccountStreamInfo clubMemberAccountStreamInfo =
                    clubAccountService.addOrDeductionPersonClubAccountBalance(
                            reqSignUpInfo.getBalanceAmount(), currentUserId,
                            respClubActivity.getClubId(), false);
            if (clubMemberAccountStreamInfo == null) {
                throw new BizException("俱乐部余额不足抵扣");
                //return APIResponse.returnFail("俱乐部余额不足抵扣");
            }
            //记录个人账户流水
            clubAccountService.recordPersonClubAccountDeductibleStream(
                    currentUserId,
                    reqSignUpInfo.getActivityId(),
                    respClubActivity.getName() + "报名费",
                    reqSignUpInfo.getPayId().byteValue(),
                    respClubActivity.getClubId(), clubMemberAccountStreamInfo,
                    preOrderAPIResponse.getData().getOrderNo(), (byte) 1,
                    memberAccountStreamStatus.byteValue());
        }


        //锁定活动人数库存
        APIResponse lockActivityPersonNum = lockActivityPersonNum(
                reqSignUpInfo, respClubActivity.getLimitNum());
        if (!lockActivityPersonNum.isRet()) {
            return lockActivityPersonNum;
        }
        int orderClubId = respClubActivity.getClubId();
        //生成业务订单
        logger.warn("生成业务订单");
        Integer orderId = this.buildBusinessOrderNo(
                currentUserId, reqSignUpInfo,
                preOrderAPIResponse.getData().getOrderNo(),
                orderTime, businessOrderNo,
                reqSignUpInfo.getActivitySignMemberInfoList().size(), orderClubId);

        //记录报名人员信息
        logger.warn("记录报名人员信息");
        try{
            recordSignUpInfo(reqSignUpInfo, orderId, respClubActivity);
        }catch (Exception e)
        {
            throw new BizException(e.getMessage());
        }


        pushActivityUserCenterTaskMsg(
                currentUserId, TaskEnum.TASK_ENUM__JOIN_ACTIVITY.getId());
        if (reqSignUpInfo.getPayAmount() != null
                && reqSignUpInfo.getPayAmount().doubleValue() > 0) {
            //不是零元订单, 需要用户调用第三方支付金额, 缓存支付信息10分钟
            redisTemplate.setWithExpireTime(rediskey, preOrderAPIResponse, 10 * 60);
        } else {
            Integer activityId = reqSignUpInfo.getActivityId();
            if (null != activityId && activityId > 0) {
                Integer groupUid = clubActivityMapper.selectUidByActivityId(activityId);
                if (null != groupUid) {
                    cppService.addOrDelIMGroupMember(groupUid, activityId, respClubActivity.getGroupId(),
                            Lists.newArrayList(currentUserId), true);
                }
            }
            String address = null;
            if (null == (address = respClubActivity.getPlaceAddress())) {
                if (null != respClubActivity.getPlaceDubboProvider()) {
                    PlaceDubboProvider pd = respClubActivity.getPlaceDubboProvider();
                    address = pd.getName();
                }
            }
            TbClub club = tbClubMapper.selectByPrimaryKey(respClubActivity.getClubId());
            activitySupportService.afterSignUpActivity(respClubActivity, currentUserId,
                    address, mainMemberInfo.getMobile(), club.getClubName(), reqSignUpInfo.getLarkAppId());
        }

        return preOrderAPIResponse;
    }

    private APIResponse validateSignUpFee(ReqSignUpInfo reqSignUpInfo,
                                          RespClubActivity respClubActivity, Integer currentUserId) {
        if (reqSignUpInfo == null || respClubActivity == null) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        if (currentUserId == null) {
            throw new BizException("用户未登陆！");
        }

        List<ActivitySignMemberInfo> memberList
                = reqSignUpInfo.getActivitySignMemberInfoList();
        if (CollectionUtils.isEmpty(memberList)) {
            return APIResponse.returnFail("报名成员不存在");
        }

        BigDecimal exchangeRMB = reqSignUpInfo.getExchangeRMB() == null
                ? new BigDecimal(0) : reqSignUpInfo.getExchangeRMB();
        BigDecimal balanceAmount = reqSignUpInfo.getBalanceAmount() == null
                ? new BigDecimal(0) : reqSignUpInfo.getBalanceAmount();

        long egg = exchangeRMB.multiply(new BigDecimal(10)).longValue();
        RespRuleDetail respRuleDetail = clubAccountService.getPersonEggsInfo(
                currentUserId, reqSignUpInfo.getDealAmount());
        if (respRuleDetail == null) {
            throw new BizException("获取个人鸟蛋资产失败！");
        }
        long useableEgg = respRuleDetail.getAccount().getAccumulate();
        if (useableEgg < egg) {
            throw new BizException("剩余鸟蛋个数为" + useableEgg + ", 不足抵扣！");
        }

        BigDecimal difVal =
                reqSignUpInfo.getDealAmount().subtract(reqSignUpInfo.getPayAmount());
        if (difVal.doubleValue() > 0) {
            if (difVal.doubleValue() != exchangeRMB.add(balanceAmount).doubleValue()) {
                return APIResponse.returnFail("报名抵扣费用有误");
            }
        }

        if (balanceAmount.doubleValue() > reqSignUpInfo.getDealAmount().doubleValue()) {
            return APIResponse.returnFail("会费抵扣费用有误");
        }

        if (exchangeRMB.doubleValue() > reqSignUpInfo.getDealAmount().doubleValue()) {
            return APIResponse.returnFail("鸟蛋抵扣费用有误");
        }

        if (respClubActivity.getFeeType().equals(Constants.BYTE_ZERO)) { //aa活动
            BigDecimal needSignUpTotalFeed =
                    new BigDecimal(memberList.size()).multiply(respClubActivity.getAaFee());
            if (needSignUpTotalFeed.doubleValue() != reqSignUpInfo.getDealAmount().doubleValue()) {
                return APIResponse.returnFail("报名费用有误");
            }
            return APIResponse.returnSuccess();
        }

        if (respClubActivity.getFeeType().equals(Constants.BYTE_ONE)) { //固定费用活动
            //计算报名的男女人数
            int manCount = 0, femaleCount = 0;
            for (ActivitySignMemberInfo memberInfo : memberList) {
                if (memberInfo.getSignUpType() == 0) {
                    if(com.alibaba.dubbo.common.utils.StringUtils.isNotEmpty(memberInfo.getMobile())
                            && memberInfo.getMobile().length() > 11)
                    {
                        throw new BizException("请输入正确的手机号码");
                    }
                }
                if (memberInfo.getGender() == Constants.BYTE_ONE) {
                    manCount++;
                }
                if (memberInfo.getGender() == Constants.BYTE_TWO) {
                    femaleCount++;
                }
            }

            BigDecimal manTotalFee = new BigDecimal(0);
            BigDecimal womenTotalFee = new BigDecimal(0);

            Boolean isClubMember = clubMemberService.isClubMember(
                    reqSignUpInfo.getOptUserId(), respClubActivity.getClubId());

            if (isClubMember) {
                manTotalFee =
                        new BigDecimal(manCount).multiply(respClubActivity.getMaleMemberFee());
                womenTotalFee =
                        new BigDecimal(femaleCount).multiply(respClubActivity.getFemaleMemberFee());
                if (!ActivityUtils.dequals(manTotalFee.add(womenTotalFee), reqSignUpInfo.getDealAmount())) {
                    return APIResponse.returnFail("你已经是会员身份，请重新进入活动详情并刷新页面后再下单！");
                }
            } else {
                manTotalFee =
                        new BigDecimal(manCount).multiply(respClubActivity.getMaleFee());
                womenTotalFee =
                        new BigDecimal(femaleCount).multiply(respClubActivity.getFemaleFee());
                if (!ActivityUtils.dequals(manTotalFee.add(womenTotalFee), reqSignUpInfo.getDealAmount())) {
                    return APIResponse.returnFail("非会员支付金额不正确，请重新进入活动详情页面核对非会员金额！");
                }
            }

        }

        return APIResponse.returnSuccess();
    }

    @Override
    public APIResponse<RespPreOrder> continuePayActivityOrder(ReqClubContinuePayOrder
                                                                      reqClubContinuePayOrder,
                                                              String appVersion,
                                                              HttpServletRequest request) {

        RedisKey rediskey = new RedisKey(RedisConstants.ACTIIVTY_FORWARD_CACHE_PREFIX,
                reqClubContinuePayOrder.getUid() + reqClubContinuePayOrder.getBusinessOrderNo()
                        + ClubConstants.USER_ACTIVITY_ORDER_PAY_RES_INFO);

        Object obj = redisTemplate.get(rediskey);
        if (obj == null) {
            return APIResponse.returnFail("订单不存在或已超时, 请重新下单");
        }

        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria()
                .andOrderNoEqualTo(reqClubContinuePayOrder.getBusinessOrderNo())
                .andIsDeleteEqualTo((byte) 0)
                .andOrderStatusEqualTo((byte) 1);

        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);
        logger.warn("订单：" + JSONObject.toJSONString(tbOrders));
        if (CollectionUtils.isEmpty(tbOrders)) {
            return APIResponse.returnFail("查询订单不存在或已超时, 请重新下单");
        }

        TbOrder tbOrder = tbOrders.get(0);

        TbSignUserExample example = new TbSignUserExample();
        example.createCriteria().andOrderIdEqualTo(tbOrder.getId()).
                andOrderUserIdEqualTo(tbOrder.getOrderUid())
                .andIsCancelEqualTo(0).andStatusEqualTo(1);
        example.setLimit(Limit.buildLimit(1, 1));
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(tbSignUsers)) {
            return APIResponse.returnFail("你还没报名该活动");
        }
        TbSignUser tbSignUser = tbSignUsers.get(0);

        APIResponse<RespClubActivity> clubActivityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId());
        if (!clubActivityAPIResponse.isRet()) {
            return APIResponse.returnFail("活动不存在");
        }

        RespClubActivity respClubActivity = clubActivityAPIResponse.getData();
        logger.warn("状态:" + respClubActivity.getStatus());
        if (!respClubActivity.getStatus().equals(Constants.BYTE_ZERO)) {
            return APIResponse.returnFail("活动已取消或暂停");
        }
        if (respClubActivity.getSignEndTime().before(new Date())) {
            return APIResponse.returnFail("活动已截止报名");
        }


        APIResponse<RespPreOrder> respPreOrderAPIResponse = (APIResponse<RespPreOrder>) obj;
        if (tbOrder.getPayType().equals(reqClubContinuePayOrder.getPayId().intValue())) {
            return respPreOrderAPIResponse;
        }


        //调用订单系统生成订单
        com.quanyan.api.APIRequest<ReqOrderSave> reqOrderSaveAPIRequest
                = new com.quanyan.api.APIRequest<>();

        ReqOrderSave reqOrderSave = new ReqOrderSave();
        reqOrderSave.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
        reqOrderSave.setSourceBusinessId(Constants.CLUB_ACTIVITY_ORDER_BUSINESS_CODE);
        reqOrderSave.setPlatformType(reqClubContinuePayOrder.getPlatformType());
        reqOrderSave.setContactMobile(tbSignUser.getMobile());
        reqOrderSave.setContactName(tbSignUser.getName());
        Integer mchId = reqClubContinuePayOrder.getMchId();
        if (mchId != null && mchId != 0) {
            reqOrderSave.setMchId(mchId); //此处为城市ID
        } else {
            reqOrderSave.setMchId(2); //此处为城市ID
        }
        reqOrderSave.setExtraParam("");//拓展字段原样返回
        reqOrderSave.setVer(appVersion);
        reqOrderSave.setNotifyURL(""); // 支付成功后回调地址
        String serverUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
        reqOrderSave.setNotifyURL(serverUrl + "/api/club/callBack/orderPaySuccess"); // 支付成功后回调地址
        reqOrderSave.setRefundNotifyURL(serverUrl + "/api/club/callBack/orderRefundNotify");
        reqOrderSave.setExceptionRefundNotify(serverUrl + "/api/club/callBack/orderExceptionRefundNotify");
        reqOrderSave.setCloseNotifyURL(serverUrl + "/api/club/callBack/orderCloseNotify");
        reqOrderSave.setOrderAmount(tbOrder.getOrderAmount());
        if (reqClubContinuePayOrder.getOpenId() != null) {
            reqOrderSave.setBuyerAccount(reqClubContinuePayOrder.getOpenId());
        }
        reqOrderSave.setOrderDescribe("俱乐部活动用户报名");
        reqOrderSave.setOrderURL("");
        reqOrderSave.setOutTradeNo(reqClubContinuePayOrder.getBusinessOrderNo()); // 业务流水号
        reqOrderSave.setUserClientIp(reqClubContinuePayOrder.getRequestIp());
        reqOrderSave.setPayTimeOut(10); //超时时间
        reqOrderSave.setUid(tbSignUser.getOrderUserId());//主要信息人ID
        reqOrderSave.setShowURL("");//订单缩略图URL
        reqOrderSave.setService("service.club");
        reqOrderSave.setEggReceiver(respClubActivity.getClubName());
        reqOrderSave.setEggInfo(respClubActivity.getName() + "报名费");

        List<ReqProductDetail> reqProductDetailList = Lists.newArrayList();
        ReqProductDetail reqProductDetail = new ReqProductDetail();
        reqProductDetail.setProductId(tbOrder.getActivityId().toString());
        reqProductDetail.setShowURL("");//产品详情URL
        reqProductDetail.setPrice(tbOrder.getOrderAmount());
        reqProductDetail.setProductDesc(respClubActivity.getActivityDesc().getBodyDesc());
        reqProductDetail.setProductName(respClubActivity.getName());
        reqProductDetail.setProductURL("");
        reqProductDetail.setQuantity(1);
        reqProductDetailList.add(reqProductDetail);
        reqOrderSave.setProductDetailList(reqProductDetailList);

        List<ReqPayInfo> reqPayInfoList = Lists.newArrayList();
        ReqPayInfo reqPayInfo = new ReqPayInfo();
        reqPayInfo.setPayId(reqClubContinuePayOrder.getPayId());//支付方式
        reqPayInfo.setAmount(tbOrder.getPayAmount()); //实付金额
        reqPayInfoList.add(reqPayInfo);

//        if (!StringUtil.isBlankOrNull(tbOrder.getCouponCode())){
//            APIResponse<RespCoupon> response = couponService.getInfoByCode(tbOrder.getCouponCode());
//            if (response == null || !response.isRet()){
//                return APIResponse.returnFail("获取优惠券信息失败！");
//            }
//            RespCoupon coupon = response.getData();
//
//            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_COUPON.getPayId()); //支付方式
//            reqPayInfo.setPayType("俱乐部优惠券");
//            reqPayInfo.setAmount(coupon.getCouponAmount());
//            reqPayInfo.setOrderType(CouponOrderType.CLUB_ACTIVITY.id.byteValue());
//            reqPayInfo.setSportType(Byte.valueOf(coupon.getSportType()));
//            reqPayInfo.setSubjectCode(coupon.getCouponCode());     //	唯一标识（优惠券CODE）
//        }
        if (tbOrder.getAccumulateAmount() != null
                && tbOrder.getAccumulateAmount().intValue() > 0) {
            reqPayInfo = new ReqPayInfo();
            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_AGES.getPayId());//支付方式
            reqPayInfo.setAmount(new BigDecimal(tbOrder.getAccumulateAmount())); //鸟蛋数
            reqPayInfoList.add(reqPayInfo);
        }
        if (tbOrder.getBalanceAmount() != null
                && tbOrder.getBalanceAmount().compareTo(BigDecimal.ZERO) == 1) {
            reqPayInfo = new ReqPayInfo();
            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_DEDUCTION.getPayId());//支付方式
            reqPayInfo.setAmount(tbOrder.getBalanceAmount()); //俱乐部余额
            reqPayInfoList.add(reqPayInfo);
        }
        reqOrderSave.setShowURLForH5(reqClubContinuePayOrder.getShowURLForH5());
        reqOrderSave.setReturnUrlForH5(reqClubContinuePayOrder.getReturnUrlForH5());
        reqOrderSave.setPayInfos(reqPayInfoList);
        reqOrderSaveAPIRequest.setData(reqOrderSave);
        logger.warn("调用订单系统生成订单:" + JSONObject.toJSONString(reqOrderSaveAPIRequest));
        respPreOrderAPIResponse = orderPayService.submitOrder(reqOrderSaveAPIRequest);
        if (!respPreOrderAPIResponse.isRet()) {
            logger.error("继续支付-调用订单系统生成订单失败 , 失败信息: " + respPreOrderAPIResponse.getErrmsg());
            logger.error("第一步-调用订单系统生成订单失败 , 失败信息: " + respPreOrderAPIResponse.getErrmsg());
            if (respPreOrderAPIResponse.getErrcode() == 21012) {
                return APIResponse.returnFail("当前支付方式不可用，请使用其他支付方式或稍后再试。");
            }
            return APIResponse.returnFail("订单生成失败,请重试!");
        }

        tbOrder.setPayType(reqClubContinuePayOrder.getPayId().byteValue());
        orderMapper.updateByPrimaryKeySelective(tbOrder);

        redisTemplate.delteKey(rediskey);
        redisTemplate.setWithExpireTime(rediskey, respPreOrderAPIResponse, 10 * 60);

        return respPreOrderAPIResponse;
    }

    /*
         * 生成活动业务订单
         * return orderId
         */
    private Integer buildBusinessOrderNo(Integer uid,
                                         ReqSignUpInfo reqSignUpInfo,
                                         String orderSystemNo,
                                         Date orderTime,
                                         String businessOrderNo,
                                         Integer applyNum, int orderClubId) {

        TbOrder tbOrder = new TbOrder();

        if (reqSignUpInfo.getPayAmount() == null
                || reqSignUpInfo.getPayAmount().doubleValue() <= 0) {
            //零元订单
            tbOrder.setOrderStatus((byte) 2); //支付成功
        } else {
            tbOrder.setOrderStatus((byte) 1); //待支付
        }
        tbOrder.setClubId(orderClubId);
        tbOrder.setSrcId(1);
        tbOrder.setPlatformType(reqSignUpInfo.getPlatformType().byteValue());
        tbOrder.setOrderUid(uid);
        tbOrder.setOrderNo(businessOrderNo);//业务系统订单号
        tbOrder.setApplyNum(applyNum);
        tbOrder.setActivityId(reqSignUpInfo.getActivityId());
        tbOrder.setCreateTime(orderTime);
        tbOrder.setOrderTradeNo(orderSystemNo);//订单系统的订单号
        tbOrder.setOrderAmount(reqSignUpInfo.getDealAmount() == null
                ? new BigDecimal(0) : reqSignUpInfo.getDealAmount()); //总金额(优惠前)
        tbOrder.setPayAmount(reqSignUpInfo.getPayAmount() == null
                ? new BigDecimal(0) : reqSignUpInfo.getPayAmount()); //实付金额
        tbOrder.setPayType(reqSignUpInfo.getPayId().byteValue());
        tbOrder.setAccumulateAmount(reqSignUpInfo.getAccumulateAmount() == null
                ? 0 : reqSignUpInfo.getAccumulateAmount().longValue()); //鸟蛋抵扣
        tbOrder.setBalanceAmount(reqSignUpInfo.getBalanceAmount() == null
                ? new BigDecimal(0) : reqSignUpInfo.getBalanceAmount()); //俱乐部余额抵扣
        tbOrder.setExchangeRmb(reqSignUpInfo.getExchangeRMB() == null
                ? new BigDecimal(0) : reqSignUpInfo.getExchangeRMB()); //抵扣的鸟蛋数对应金额
//        ReqClubCoupon coupon = reqSignUpInfo.getCoupon();       //优惠券
//        if (coupon != null) {
//            tbOrder.setSportTypeId(coupon.getSportType().intValue());
//            tbOrder.setCouponCode(coupon.getSubjectCode());
//            tbOrder.setCouponAmount(coupon.getAmount());
//        }
        logger.warn("生成业务订单结果：" + JSONObject.toJSONString(tbOrder));
        orderMapper.insertSelective(tbOrder);

        return tbOrder.getId();
    }

    /**
     * 记录报名人员信息
     */
    private void recordSignUpInfo(ReqSignUpDetail reqSignUpInfo, Integer orderId,
                                  RespClubActivity respClubActivity) {
        List<ActivitySignMemberInfo> members = reqSignUpInfo.getActivitySignMemberInfoList();
        for (int i = 0; i < members.size(); i++) {
            ActivitySignMemberInfo memberInfo = members.get(i);
            TbSignUser tbSignUser = new TbSignUser();
            if (memberInfo.getSignUpType() == 1) {
                StringBuffer sb = new StringBuffer();
                sb.append(memberInfo.getName());
                sb.append("代" + i);
                tbSignUser.setName(sb.toString());
            } else {
                tbSignUser.setName(memberInfo.getName());
                if (null != respClubActivity.getRequireField() && !"".equals(respClubActivity)) {
                    activitySupportService.setRequireFields(respClubActivity.getRequireField(),
                            reqSignUpInfo, tbSignUser);
                }
            }
            tbSignUser.setCreateTime(new Date());
            tbSignUser.setGender(memberInfo.getGender());
            tbSignUser.setMobile(memberInfo.getMobile());
            tbSignUser.setActivityId(reqSignUpInfo.getActivityId());
            tbSignUser.setIsReplace(memberInfo.getSignUpType());
            tbSignUser.setOrderUserId(
                    memberInfo.getUid() == null ? null : memberInfo.getUid());
            tbSignUser.setManageType(0);
            tbSignUser.setIsCancel(0);
            tbSignUser.setPayChannel(0);
            tbSignUser.setStatus(1);
            tbSignUser.setOrderId(orderId); //订单表的id
            signUserMapper.insertSelective(tbSignUser);
        }
    }

    private void pushNotify(RespClubActivity respClubActivity,
                            Integer uid,
                            Integer type,
                            List<Integer> toUid) {
        //批量查询用户信息
        APIResponse<List<RespUserInfoBase>> respUserInfoBase =
                userServiceFacade.batchQueryUserInfo(Lists.<Integer>newArrayList(uid));
        if (!respUserInfoBase.isRet() || CollectionUtils.isEmpty(respUserInfoBase.getData())) {
            return;
        }

        RespUserInfoBase userInfoBase = respUserInfoBase.getData().get(0);
        ActivityRelatedMsg activityRelatedMsg = new ActivityRelatedMsg();
        activityRelatedMsg.setActivityId(respClubActivity.getActivityId());
        activityRelatedMsg.setActivityName(respClubActivity.getName());
        activityRelatedMsg.setAvatar(userInfoBase.getIcon());
        activityRelatedMsg.setClubName(respClubActivity.getClubName());
        activityRelatedMsg.setClubId(respClubActivity.getClubId());
        activityRelatedMsg.setToUid(toUid);
        activityRelatedMsg.setUserNick(userInfoBase.getNickName());
        activityRelatedMsg.setPosterId(respClubActivity.getPosterPicId());

        if (type == 1) {
            cppService.pushActivitySignUpSuccess(activityRelatedMsg);
        } else if (type == 2) {
            cppService.pushActivityAppraise(activityRelatedMsg);
        } else if (type == 3) {
            RespClubFinanceBillDetail respClubFinanceBillDetail =
                    clubFinanceMgmService.getClubFinanceBillDetail(
                            activityRelatedMsg.getActivityId(),
                            activityRelatedMsg.getClubId(), Constants.IS_YES);
            if (respClubFinanceBillDetail == null) {
                logger.warn("没有活动结算详情");
                return;
            }
            cppService.pushActivitySettlement(activityRelatedMsg, respClubFinanceBillDetail);
        } else if (type == 4) {
            RespClubFinanceBillDetail respClubFinanceBillDetail =
                    clubFinanceMgmService.getClubFinanceBillDetail(
                            activityRelatedMsg.getActivityId(),
                            activityRelatedMsg.getClubId(), Constants.IS_YES);
            if (respClubFinanceBillDetail == null) {
                logger.warn("没有活动结算详情");
                return;
            }
            cppService.pushActivityAutoSettle(activityRelatedMsg, respClubFinanceBillDetail);
        }
    }

    /**
     * 锁定活动人数库存
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse lockActivityPersonNum(ReqSignUpInfo reqSignUpInfo, Integer limitNum) {

        List<ActivitySignMemberInfo> activitySignMemberInfoList
                = reqSignUpInfo.getActivitySignMemberInfoList();
        if (CollectionUtils.isEmpty(activitySignMemberInfoList)) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }

        int signUpTotalNum = activitySignMemberInfoList.size(); //此次报名总人数

        Map<String, Object> paraMap = Maps.newHashMap();
        paraMap.put("activityId", reqSignUpInfo.getActivityId());
        paraMap.put("alreadySignTotalNum", signUpTotalNum);
        paraMap.put("limitNum", limitNum);

        if (limitNum != null && limitNum >= 0) {
            logger.warn("锁定报名人数库存：" + JSONObject.toJSONString(paraMap));
            int count = 0;
            logger.warn("-------限制人数为：" + limitNum);
            count = clubActivityMapper.updateAlreadyLockSignTotalNum(paraMap);
            logger.warn("count:" + count);
            if (count == 0) {
                throw new BizException("报名人数超过活动规定限制");
            }
        }

        //添加报名人数
        int count = clubActivityMapper.updateAlreadySignTotalNum(paraMap);
        if (count == 0) {
            throw new BizException("报名人数超过活动规定限制");
        }
        return APIResponse.returnSuccess();
    }


    private APIResponse<RespPreOrder> invokeRpcBuildClubActivityOrder(
            ReqSignUpInfo reqSignUpInfo,
            ActivitySignMemberInfo mainMemberInfo,
            RespClubActivity respClubActivity,
            String requestIp,
            HttpServletRequest request,
            String businessOrderNo, String appVersion) {

        com.quanyan.api.APIRequest<ReqOrderSave> reqOrderSaveAPIRequest
                = new com.quanyan.api.APIRequest<>();

        ReqOrderSave reqOrderSave = new ReqOrderSave();
        reqOrderSave.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
        reqOrderSave.setSourceBusinessId(Constants.CLUB_ACTIVITY_ORDER_BUSINESS_CODE);
        reqOrderSave.setPlatformType(reqSignUpInfo.getPlatformType());
        reqOrderSave.setContactMobile(mainMemberInfo.getMobile());
        reqOrderSave.setContactName(mainMemberInfo.getName());
        Integer mchId = reqSignUpInfo.getMchId();
        if (mchId != null && mchId != 0) {
            reqOrderSave.setMchId(mchId); //此处为城市ID
        } else {
            reqOrderSave.setMchId(2); //此处为城市ID
        }
        reqOrderSave.setExtraParam("");//拓展字段原样返回
        reqOrderSave.setVer(appVersion);
        String serverUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
        reqOrderSave.setNotifyURL(serverUrl + "/api/club/callBack/orderPaySuccess"); // 支付成功后回调地址
        reqOrderSave.setRefundNotifyURL(serverUrl + "/api/club/callBack/orderRefundNotify");
        reqOrderSave.setExceptionRefundNotify(serverUrl + "/api/club/callBack/orderExceptionRefundNotify");
        reqOrderSave.setCloseNotifyURL(serverUrl + "/api/club/callBack/orderCloseNotify");
        reqOrderSave.setOrderAmount(reqSignUpInfo.getDealAmount());
        if (reqSignUpInfo.getOpenId() != null)
            reqOrderSave.setBuyerAccount(reqSignUpInfo.getOpenId());

        logger.warn("1");
        reqOrderSave.setOrderDescribe(respClubActivity.getName());
        reqOrderSave.setOrderURL("");
        reqOrderSave.setOutTradeNo(businessOrderNo); // 业务流水号
        reqOrderSave.setUserClientIp(requestIp);
        reqOrderSave.setPayTimeOut(10); //超时时间
        reqOrderSave.setUid(mainMemberInfo.getUid());//主要信息人ID
        reqOrderSave.setShowURL("");//订单缩略图URL
        reqOrderSave.setService("service.club");
        reqOrderSave.setEggReceiver(respClubActivity.getClubName());
        reqOrderSave.setEggInfo(respClubActivity.getName() + "报名费");
        logger.warn("2");
        List<ReqProductDetail> reqProductDetailList = Lists.newArrayList();
        ReqProductDetail reqProductDetail = new ReqProductDetail();
        try
        {
            logger.warn("2.2");
            reqProductDetail.setProductId(respClubActivity.getActivityId().toString());
            reqProductDetail.setShowURL("");//产品详情URL
            reqProductDetail.setPrice(reqSignUpInfo.getDealAmount());
            reqProductDetail.setProductDesc(respClubActivity.getActivityDesc().getBodyDesc());
            reqProductDetail.setProductName(respClubActivity.getName());
            reqProductDetail.setProductURL("");
            reqProductDetail.setQuantity(1);
            reqProductDetailList.add(reqProductDetail);
            reqOrderSave.setProductDetailList(reqProductDetailList);
        }catch (Exception e)
        {
            logger.warn(e.getMessage());
        }
        logger.warn("3");
        List<ReqPayInfo> reqPayInfoList = Lists.newArrayList();
        ReqPayInfo reqPayInfo = new ReqPayInfo();

//        if (reqSignUpInfo.getCoupon() != null && reqSignUpInfo.getCoupon().getAmount().doubleValue() > 0){
//            APIResponse<RespCoupon> response = couponService.getInfoByCode(reqSignUpInfo.getCoupon().getSubjectCode());
//            if (response == null || !response.isRet()){
//                return APIResponse.returnFail("获取优惠券信息失败！");
//            }
//            RespCoupon coupon = response.getData();
//            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_COUPON.getPayId()); //支付方式
//            reqPayInfo.setPayType("俱乐部优惠券");
//            reqPayInfo.setAmount(coupon.getCouponAmount());
//            reqPayInfo.setOrderType(CouponOrderType.CLUB_ACTIVITY.id.byteValue());
//            reqPayInfo.setSportType(reqSignUpInfo.getCoupon().getSportType());
//            reqPayInfo.setSubjectCode(coupon.getCouponCode());     //	唯一标识（优惠券CODE）
//        }

        if (reqSignUpInfo.getPayAmount() != null
                && reqSignUpInfo.getPayAmount().doubleValue() > 0) {
            reqPayInfo.setPayId(reqSignUpInfo.getPayId());//支付方式
            reqPayInfo.setAmount(reqSignUpInfo.getPayAmount()); //实付金额
            reqPayInfoList.add(reqPayInfo);
        }
        logger.warn("4");
        if (reqSignUpInfo.getAccumulateAmount() != null
                && reqSignUpInfo.getAccumulateAmount().doubleValue() > 0) {
            reqPayInfo = new ReqPayInfo();
            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_AGES.getPayId());//支付方式
            reqPayInfo.setAmount(reqSignUpInfo.getAccumulateAmount()); //鸟蛋数
            reqPayInfoList.add(reqPayInfo);
        }
        logger.warn("5");
        if (reqSignUpInfo.getBalanceAmount() != null
                && reqSignUpInfo.getBalanceAmount().doubleValue() > 0) {
            reqPayInfo = new ReqPayInfo();
            reqPayInfo.setPayId(PayWayEnum.PAY_WAY_FOR_DEDUCTION.getPayId());//支付方式
            reqPayInfo.setAmount(reqSignUpInfo.getBalanceAmount()); //俱乐部余额
            reqPayInfoList.add(reqPayInfo);
        }
        logger.warn("6");
        reqOrderSave.setPayInfos(reqPayInfoList);
        reqOrderSave.setReturnUrlForH5(reqSignUpInfo.getReturnUrlForH5());
        reqOrderSave.setShowURLForH5(reqSignUpInfo.getShowURLForH5());
        //增加区分app的表示larkAppId
        reqOrderSave.setLarkAppId(reqSignUpInfo.getLarkAppId());
        reqOrderSaveAPIRequest.setData(reqOrderSave);
        logger.warn("调用订单系统支付参数：" + JSONObject.toJSONString(reqOrderSaveAPIRequest));
        APIResponse<RespPreOrder> respPreOrderAPIResponse =
                orderPayService.submitOrder(reqOrderSaveAPIRequest);
        if (!respPreOrderAPIResponse.isRet()) {
            logger.error("第一步-调用订单系统生成订单失败 , 失败信息: " + respPreOrderAPIResponse.getErrmsg());
            if (respPreOrderAPIResponse.getErrcode() == 21012) {
                return respPreOrderAPIResponse;
            }
            return APIResponse.returnFail("订单生成失败,请重试!");
        }
        return respPreOrderAPIResponse;
    }


    private APIResponse<RespClubActivity> validatedUserSignUp(ReqSignUpInfo reqSignUpInfo) {
        if (reqSignUpInfo.getOptUserId() == null
                || reqSignUpInfo.getOptUserId().intValue() == 0) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }

        RespClubActivity respClubActivity =
                activityCRUDService.selectClubActivityById(reqSignUpInfo.getActivityId());
        if (null == respClubActivity) {
            return APIResponse.returnFail("活动不存在");
        }

        Long currentTime = new Date().getTime();
        if (!respClubActivity.getStatus().equals(Constants.BYTE_ZERO)) {
            return APIResponse.returnFail("活动已经取消或暂停");
        }

        if (currentTime >= respClubActivity.getEndTime().getTime()) {
            return APIResponse.returnFail("活动已经结束");
        }

        if (currentTime >= respClubActivity.getSignEndTime().getTime()) {
            return APIResponse.returnFail("已过活动报名截止时间");
        }

        if (respClubActivity.getSignUpType().intValue() == 1) {
            //会员才能报名
            boolean isClubMember = clubMemberService.isClubMember(
                    reqSignUpInfo.getOptUserId(), respClubActivity.getClubId());
            if (!isClubMember) {
                return APIResponse.returnFail("需要成为该俱乐部会员才能报名活动");
            }
        }

        if (respClubActivity.getLimitNum() > 0) {
            if (reqSignUpInfo.getActivitySignMemberInfoList().size()
                    > (respClubActivity.getLimitNum() - respClubActivity.getAlreadySignTotalNum())) {
                return APIResponse.returnFail("活动报名人数超过规定限制");
            }
        }


        //0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消
        TbOrderExample example = new TbOrderExample();
        example.createCriteria().andActivityIdEqualTo(reqSignUpInfo.getActivityId()).
                andOrderUidEqualTo(reqSignUpInfo.getOptUserId()).andIsDeleteEqualTo((byte) 0)
                .andOrderStatusIn(Lists.<Byte>newArrayList((byte) 1, (byte) 2, (byte) 7));
        List<TbOrder> tbOrders = orderMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(tbOrders)) {
            for (TbOrder tbOrder : tbOrders) {
                if (tbOrder.getOrderStatus().equals(Constants.BYTE_ONE)) {
                    return APIResponse.returnFail("你有一笔待支付订单");
                }
                if (tbOrder.getOrderStatus().equals((byte) 2)) {
                    return APIResponse.returnFail("你已经报名过该活动了");
                }
                if (tbOrder.getOrderStatus().equals((byte) 7)) {
                    return APIResponse.returnFail("你已经报名过该活动了");
                }
            }
        }

        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andActivityIdEqualTo(reqSignUpInfo.getActivityId()).
                andOrderUidEqualTo(reqSignUpInfo.getOptUserId()).andIsDeleteEqualTo((byte) 0)
                .andOrderStatusEqualTo((byte) 1);
        tbOrderExample.setLimit(Limit.buildLimit(1, 3));
        int count = orderMapper.countByExample(tbOrderExample);
        if (count >= 2) {
            return APIResponse.returnFail("你已经有两个或以上的活动未支付订单，请先支付或取消，再重新下单");
        }

//        String mainMemberMobile = null;
//        for (ActivitySignMemberInfo memberInfo : reqSignUpInfo.getActivitySignMemberInfoList()) {
//            if (memberInfo.getSignUpType().intValue() == 0) {
//                mainMemberMobile = memberInfo.getMobile();
//                break;
//            }
//        }

        if ((reqSignUpInfo.getPayAmount() == null
                || reqSignUpInfo.getPayAmount().doubleValue() <= 0)
                && reqSignUpInfo.getIsSendMsgValidated()) {

            Date oneDayBefore = DateTime.now().minusDays(1).secondOfDay().getDateTime().toDate();
            tbOrderExample = new TbOrderExample();
            tbOrderExample.createCriteria().andOrderUidEqualTo(reqSignUpInfo.getOptUserId())
                    .andOrderStatusEqualTo((byte) 2)
                    .andPayAmountEqualTo(new BigDecimal(0))
                    .andCreateTimeBetween(oneDayBefore, new Date());
            tbOrderExample.setOrderByClause(" create_time desc");
            tbOrderExample.setLimit(Limit.buildLimit(1, 3));
            Integer zeroOrderSize = orderMapper.countByExample(tbOrderExample);
            if (zeroOrderSize == null || zeroOrderSize < 2) {
                return APIResponse.returnSuccess(respClubActivity);
            }

            //有两笔连续的零元订单 , 返回错误码
            return APIResponse.returnFail(ApiResponseEnum.HAVE_TWO_ZERO_ORDER);
        }

        return APIResponse.returnSuccess(respClubActivity);
    }

    /**
     * 活动订单详情
     */
    @Override
    public APIResponse<ResActivityOrderDetail> activityOrderDetail(Integer activityId,
                                                                   Integer currentUserId,
                                                                   String businessOrderNo) {
        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria()
                .andActivityIdEqualTo(activityId)
                .andOrderNoEqualTo(businessOrderNo)
                .andIsDeleteEqualTo((byte) 0);
        tbOrderExample.setLimit(Limit.buildLimit(1, 1));
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);
        if (CollectionUtils.isEmpty(tbOrders)) {
            return APIResponse.returnFail("活动订单不存在");
        }

        //获取俱乐部活动详情
        RespClubActivity respClubActivity =
                activityCRUDService.selectClubActivityById(activityId);
        logger.warn("respClubActivity" + JSONObject.toJSONString(respClubActivity));
        if (null == respClubActivity) {
            return APIResponse.returnFail("活动不存在");
        }
        //活动订单
        TbOrder tbOrder = tbOrders.get(0);
        logger.warn("活动订单：" + JSONObject.toJSONString(tbOrder));
        //获取参加活动人员
        TbSignUserExample tbSignUserExample = new TbSignUserExample();
        TbSignUserExample.Criteria criteria = tbSignUserExample.createCriteria();
        criteria.andActivityIdEqualTo(activityId);
        criteria.andOrderIdEqualTo(tbOrder.getId());

        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(tbSignUserExample);
        ResActivityOrderDetail resActivityOrderDetail = new ResActivityOrderDetail();
        if(CollectionUtils.isNotEmpty(tbSignUsers))
        {
            if(null != tbSignUsers.get(0) && tbSignUsers.get(0).getManageType() == 4)
            {
                resActivityOrderDetail.setIsSign(1);
            }
        }
        resActivityOrderDetail.setBusinessOrderNo(tbOrder.getOrderNo());
        resActivityOrderDetail.setActivityStartTime(respClubActivity.getStartTime().getTime());
        resActivityOrderDetail.setPayTime(tbOrder.getPayTime().getTime());
        resActivityOrderDetail.setOrderCreateTime(tbOrder.getCreateTime().getTime());
        resActivityOrderDetail.setPayAmount(tbOrder.getPayAmount());
        resActivityOrderDetail.setRespClubActivity(respClubActivity);
        resActivityOrderDetail.setSignUpInfo(tbSignUsers);
        resActivityOrderDetail.setExchangeRMB(tbOrder.getExchangeRmb());
        if (null != tbOrder.getPayType()) {
            resActivityOrderDetail.setPayId(tbOrder.getPayType().intValue());
        }
        resActivityOrderDetail.setCurTime(new Date().getTime());
        resActivityOrderDetail.setClubPersonMoney(tbOrder.getBalanceAmount());
        resActivityOrderDetail.setAccumulate(tbOrder.getAccumulateAmount());
        resActivityOrderDetail.setCouponAmount(tbOrder.getCouponAmount());

        Date now = new Date();
        if (now.getTime() < respClubActivity.getStartTime().getTime()) {
            resActivityOrderDetail.setActivityStatus(1); //活动待开始
        } else if (now.getTime() > respClubActivity.getEndTime().getTime()) {
            resActivityOrderDetail.setActivityStatus(2); //活动已经结束
        } else {
            resActivityOrderDetail.setActivityStatus(3); //活动进行中
        }
        logger.warn("activityStatus:" + tbOrder.getCancelType().intValue());
        if (tbOrder.getCancelType().equals(Constants.BYTE_TWO)
                || tbOrder.getCancelType().equals((byte) 3)
                || tbOrder.getCancelType().equals((byte) 4)) {
            logger.warn("activityStatus0:" + tbOrder.getCancelType().intValue());
            resActivityOrderDetail.setActivityStatus(4); //活动已取消
            logger.warn("activityStatus1:" + resActivityOrderDetail.getActivityStatus());
        }
        logger.warn("activityStatus2:" + resActivityOrderDetail.getActivityStatus());

        //数据库订单状态: 0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消
        logger.warn("OrderStatus:" + tbOrder.getOrderStatus());
        switch (tbOrder.getOrderStatus().intValue()) {
            case 0:
            case 8:
                resActivityOrderDetail.setOrderStatus(2); //订单已取消
                break;
            case 1:
            case 3:
                resActivityOrderDetail.setOrderStatus(1); //订单待付款
                break;
            case 2:
                resActivityOrderDetail.setOrderStatus(3); //订单已付款
                if (now.getTime() > respClubActivity.getEndTime().getTime()) {
                    resActivityOrderDetail.setOrderStatus(6); //订单已完成
                }
                break;
            case 4:
                resActivityOrderDetail.setOrderStatus(4); //订单退款中
                break;
            case 5:
                resActivityOrderDetail.setOrderStatus(5); //订单已退款
                break;
            case 6:
                resActivityOrderDetail.setOrderStatus(6); ///订单已完成
                break;
            case 7:
                resActivityOrderDetail.setOrderStatus(7); //订单已评价
                break;
            default:
                break;
        }
        //APP2.0 AA结算活动退款明细
        if (respClubActivity.getIsSettle() == 1 && respClubActivity.getFeeType() == 0) {
            TbAASettlementRefundDetail detail =
                    clubAccountService.getTbAASettlementRefundDetail(
                            businessOrderNo, activityId, currentUserId);
            if (null != detail) {
                ResAASettlementRefundDetail resDetail = new ResAASettlementRefundDetail();
                resDetail.setRefundAccumulateAmount(detail.getRefundAccumulateAmount());
                resDetail.setRefundBalanceAmount(detail.getRefundBalanceAmount());
                resDetail.setRefundStatus(detail.getRefundStatus());
                resDetail.setRefundThirdPartyAmount(detail.getRefundThirdPartyAmount());
                resActivityOrderDetail.setResAASettlementRefundDetail(resDetail);
            }
        }

//        ReqIsComment reqIsComment = new ReqIsComment();
//        reqIsComment.setUid(currentUserId);
//        reqIsComment.setSystemCode(Constants.CLUB_SYSTEM_CODE);
//        reqIsComment.setBusinessCode(Constants.CLUB_ACTIVITY_COMMENT_BUSINESS_CODE);
//        reqIsComment.setBusinessId(activityId);
//        APIResponse<Boolean> apiResponse = commentServiceFacade.checkIsComment(reqIsComment);
//        if (apiResponse.isRet() && apiResponse.getData()) {
//            resActivityOrderDetail.setOrderStatus(7);//已评价
//        }

        return APIResponse.returnSuccess(resActivityOrderDetail);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse activityAppraise(Integer userId, Integer activityId,
                                        Integer score, String content,
                                        String businessOrderNo, List<String> lstPic) {

        APIResponse<RespClubActivity> activityAPIResponse
                = queryClubActivityById(activityId, null);
        if (!activityAPIResponse.isRet()) {
            return activityAPIResponse;
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();

        TbSignUserExample example = new TbSignUserExample();
        example.createCriteria().andActivityIdEqualTo(activityId).
                andOrderUserIdEqualTo(userId).andIsCancelEqualTo(0).andStatusEqualTo(1);
        example.setLimit(Limit.buildLimit(1, 1));
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(tbSignUsers)) {
            return APIResponse.returnFail("你还没报名该活动");
        }

        if (respClubActivity.getEndTime().getTime() > new Date().getTime()) {
            return APIResponse.returnFail("活动未结束");
        }

        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria().andOrderNoEqualTo(businessOrderNo)
                .andOrderUidEqualTo(userId)
                .andActivityIdEqualTo(activityId);
        List<TbOrder> orders = orderMapper.selectByExample(orderExample);
        if (CollectionUtils.isEmpty(orders)) {
            return APIResponse.returnFail("订单不存在");
        }
        TbOrder tbOrder = orders.get(0);

        //0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消
        if (tbOrder.getOrderStatus().equals((byte) 1)
                || tbOrder.getOrderStatus().equals((byte) 3)
                || tbOrder.getOrderStatus().equals((byte) 4)
                || tbOrder.getOrderStatus().equals((byte) 5)
                || tbOrder.getOrderStatus().equals((byte) 8)) {
            return APIResponse.returnFail("无效订单, 评价失败");
        }

        if (tbOrder.getOrderStatus().equals((byte) 7)) {
            return APIResponse.returnFail("你已经评价过该活动了");
        }

        tbOrder.setOrderStatus((byte) 7);
        orderMapper.updateByPrimaryKeySelective(tbOrder);

        com.quanyan.comment.reqeust.ReqCommentParam reqCommentParam =
                new com.quanyan.comment.reqeust.ReqCommentParam();

        reqCommentParam.setSystemCode(Constants.CLUB_SYSTEM_CODE);
        reqCommentParam.setBusinessCode(Constants.CLUB_ACTIVITY_COMMENT_BUSINESS_CODE);
        reqCommentParam.setBusinessId(activityId);
        reqCommentParam.setCommentContent(Strings.isNullOrEmpty(content) ? null : content);
        reqCommentParam.setCommentType(1);
        reqCommentParam.setCommonParam(respClubActivity.getClubId());
        reqCommentParam.setFromUserId(userId);
        reqCommentParam.setScore(score == null ? new Double(0) : new Double(score));
        if (null != lstPic && lstPic.size() > 0) {
            reqCommentParam.setLstPic(lstPic);
        }
        logger.warn("开始调用评论系统，入参：{}" + reqCommentParam);
        APIResponse apiResponse = commentServiceFacade.commentAdd(reqCommentParam);
        if (!apiResponse.isRet()) {
            logger.error("调用评论系统失败, 失败信息: " + apiResponse.getErrmsg());
            throw new BizException("调用评论系统失败, 失败信息: " + apiResponse.getErrmsg());
        }
        clubIntegralService.modifyClubCommentStar(respClubActivity.getClubId(), score);
        pushActivityUserCenterTaskMsg(userId, TaskEnum.TASK_ENUM__COMMENT_ACTIVITY.getId());
        RespExperienceParameter respExperienceParameter =
                clubXpLevelService.getExperienceParameter(EVALUATION_ACTIVITY);
        Integer count = clubXpLevelService.countByCurDate(
                EVALUATION_ACTIVITY, respClubActivity.getClubId());
        if (respExperienceParameter.getExpNumber() != null && count < respExperienceParameter.getExpNumber()) {
            RespClubXpLevelMsg respClubXpLevelMsg = getRespClubXpLevelMsg(userId, respClubActivity);
            respClubXpLevelMsg.setExpName(EVALUATION_ACTIVITY);
            addClubExp(respClubXpLevelMsg);
        }

        pushNotify(respClubActivity, userId, 2,
                Lists.<Integer>newArrayList(respClubActivity.getUid()));

        return APIResponse.returnSuccess();
    }


    @Override
    public APIResponse<Map<String, Object>> memberManageList(
            Integer userId, Integer activityId, Integer clubId) {
        if (!clubMemberService.isClubAdminMember(userId, clubId)) {
            return APIResponse.returnFail("请先加入俱乐部并努力获取管理员权限。");
        }
        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(activityId);
        if (!activityAPIResponse.isRet()) {
            return APIResponse.returnFail("活动不存在");
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        if (respClubActivity.getStatus().equals((byte) 2)) {
            return APIResponse.returnFail("活动已取消");
        }

        Map<String, Object> retMap = Maps.newHashMapWithExpectedSize(2);
        Integer settleStatus = respClubActivity.getIsSettle();
        logger.warn("settkeStatus = " + settleStatus);
        switch (settleStatus.intValue()) {
            case 0: //活动未结算
                retMap.put("settleStatus", 0);
                break;
            case 1: //活动已结算
                retMap.put("settleStatus", 1);
                break;
            case 2: //活动现场管理已提交(未结算)
                retMap.put("settleStatus", 2);
                break;
            default:
                break;
        }

        List<ResClubActivityMemberManage> resClubActivityMemberManages =
                getTbSignUsers(userId, activityId, clubId);
        if (resClubActivityMemberManages == null) {
            return APIResponse.returnFail("无报名人员");
        }

        retMap.put("memberManages", resClubActivityMemberManages);
        retMap.put("serverTime", new Date());
        retMap.put("activityEndTime", respClubActivity.getEndTime());
        return APIResponse.returnSuccess(retMap);
    }

    private List<ResClubActivityMemberManage> getTbSignUsers(Integer uid, Integer activityId, Integer clubId) {
        TbSignUserExample tbSignUserExample = new TbSignUserExample();
        tbSignUserExample.createCriteria().andActivityIdEqualTo(activityId).andStatusNotEqualTo(-1);//排除未支付
        tbSignUserExample.setLimit(Limit.buildLimit(1, Integer.MAX_VALUE));
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(tbSignUserExample);
        logger.warn("查询sql, 报名用户列表 : " + JSON.toJSONString(tbSignUsers));
        tbSignUsers = filterSignUserList(tbSignUsers);
        if (CollectionUtils.isEmpty(tbSignUsers)) {
            return null;
        }

        List<ResClubActivityMemberManage> memberManages =
                buildClubActivityMemberManage(uid, tbSignUsers, activityId, clubId);

        return memberManages;
    }

    private List<TbSignUser> filterSignUserList(List<TbSignUser> originalSignUsers) {

        if (CollectionUtils.isEmpty(originalSignUsers)) {
            return null;
        }

        List<TbSignUser> finallySignUser = Lists.newArrayList();

        Map<Integer, Integer> orderIdFilterMap = Maps.newHashMap();

        for (TbSignUser signUser : originalSignUsers) {

            if (signUser.getManageType().intValue() != 1//请假
                    || signUser.getIsReplace().intValue() != 0
                    || signUser.getOrderId() == null
                    || signUser.getOrderUserId() == null) {
                continue;
            }

            for (TbSignUser filterSignUser : originalSignUsers) {

                if (signUser.getManageType().intValue() != 1//请假
                        || signUser.getIsReplace().intValue() != 0
                        || signUser.getOrderId() == null
                        || filterSignUser.getOrderUserId() == null) {
                    continue;
                }

                if (filterSignUser.getOrderUserId().intValue() !=
                        signUser.getOrderUserId().intValue()) {
                    continue;
                }

                if (filterSignUser.getOrderId().intValue()
                        == signUser.getOrderId().intValue()) {
                    continue;
                }

                if (filterSignUser.getIsCancel().intValue() == 1) {
                    orderIdFilterMap.put(
                            filterSignUser.getOrderId(), filterSignUser.getOrderId());
                }
            }
        }

        logger.warn("orderIdFilterMap 集合: " + JSON.toJSONString(orderIdFilterMap));

        for (TbSignUser signUser : originalSignUsers) {
            Integer orderId = orderIdFilterMap.get(signUser.getOrderId());
            if (orderId != null) {
                logger.warn("filter: orderId" + JSON.toJSONString(orderId));
                continue;
            }
            if (signUser.getOrderId() != null) {
                TbOrder tbOrder = orderMapper.selectByPrimaryKey(signUser.getOrderId());
                if (tbOrder.getOrderStatus() == 1) {
                    continue;
                }
            }
            finallySignUser.add(signUser);
        }

        return finallySignUser;
    }

    private List<RespClubActivityMember> getActivityMember(Integer uid, Integer activityId, boolean isAdmin) {
        TbSignUserExample tbSignUserExample = new TbSignUserExample();
        tbSignUserExample.createCriteria()
                .andActivityIdEqualTo(activityId).andOrderIdIsNotNull()
                .andStatusEqualTo(1).andIsCancelEqualTo(0);//有效
        tbSignUserExample.setLimit(Limit.buildLimit(1, Integer.MAX_VALUE));
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(tbSignUserExample);
        if (CollectionUtils.isEmpty(tbSignUsers)) {
            return null;
        }

        List<RespClubActivityMember> memberManages = buildClubActivityMember(uid, tbSignUsers, isAdmin);

        return memberManages;
    }

    public List<RespClubActivityMember> buildClubActivityMember(Integer uid, List<TbSignUser> tbSignUsers, boolean isAdmin) {
        List<Byte> orderStatus = new ArrayList<Byte>();
        orderStatus.add(Constants.BYTE_TWO);
        orderStatus.add((byte) 7);
        orderStatus.add((byte) 6);
        List<Integer> userIds = Lists.newArrayList();
        for (TbSignUser user : tbSignUsers) {
            if (user.getOrderUserId() != null) {
                userIds.add(user.getOrderUserId());
            }
        }

        //批量查询用户信息
        //APP3.0需求 获取成员备注
        logger.warn("调用用户中心，入参:{}", userIds);
        APIResponse<List<RespUserInfoDetail>> respUserInfoBase = null;
        if (null == uid) {
            respUserInfoBase = userServiceFacade.batchQueryUserInfoDetail(userIds);
        } else {
            respUserInfoBase =
                    userServiceFacade.batchQueryUserInfoDetail(uid, userIds);
        }
        List<RespUserInfoDetail> respUserInfoBases = new ArrayList<RespUserInfoDetail>();
        if (respUserInfoBase.isRet()) {
            respUserInfoBases = respUserInfoBase.getData();
        }
        Map<Integer, List<RespOpenUserInterest>> integerListMap =
                userServiceFacade.batchQueryUserInterest(userIds);
        Map<Integer, String> userIdAndAvatarMap = Maps.newHashMap();
        Map<Integer, RespUserInfoDetail> userIdAndInfo = Maps.newHashMap();
        Map<Integer, Integer> userIdAndLevel = Maps.newHashMap();
        for (RespUserInfoDetail userInfo : respUserInfoBases) {
            if (null != userInfo) {
                userIdAndInfo.put(userInfo.getUid(), userInfo);
                userIdAndAvatarMap.put(userInfo.getUid(), userInfo.getIcon());
                userIdAndLevel.put(userInfo.getUid(), userInfo.getLevelDe());
            }
        }

        List<RespClubActivityMember> retList = Lists.newArrayList();

        for (TbSignUser user : tbSignUsers) {
            RespClubActivityMember mainMember = new RespClubActivityMember();
            if (user.getIsReplace().intValue() == 1
                    || user.getOrderId() == null) {
                continue;//补报名人没有订单
            }
            if (user.getManageType() != 2) {
                TbOrderExample orderExample = new TbOrderExample();
                orderExample.createCriteria().andIdEqualTo(user.getOrderId())
                        .andIsDeleteEqualTo(Constants.BYTE_ZERO).andOrderStatusIn(orderStatus);
                List<TbOrder> orders = orderMapper.selectByExample(orderExample);
                if (null == orders || orders.size() == 0) {
                    continue;
                }
            }

            List<RespClubActivityMember> replaceMembers = Lists.newArrayList();
            for (TbSignUser userTwice : tbSignUsers) {
                RespClubActivityMember replaceMember = new RespClubActivityMember();
                if (userTwice.getOrderId() == null) {
                    continue;//补报名人没有订单
                }
                if (userTwice.getIsReplace().intValue() != 1) {
                    continue;//代报名
                }
                if (userTwice.getOrderId().intValue() != user.getOrderId().intValue()) {
                    continue;//订单号是同一单
                }
                replaceMember.setName(userTwice.getName());
                replaceMember.setGender(userTwice.getGender());
                replaceMembers.add(replaceMember);//是当前这个付款人的代报名
            }
            List<String> interests = new ArrayList<String>();
            if (null != integerListMap.get(user.getOrderUserId())) {
                List<RespOpenUserInterest> list = integerListMap.get(user.getOrderUserId());
                if (null != list && list.size() > 0) {
                    for (RespOpenUserInterest interest : list) {
                        if (null == interest) {
                            continue;
                        }
                        interests.add(interest.getName());
                    }
                }
            }
            //APP3.0需求 成员列表增加返回手机号
            if (isAdmin) {
                mainMember.setMobile(userIdAndInfo.get(user.getOrderUserId()).getMobile());
            }
            //APP3.0需求 成员列表增加返回备注
            mainMember.setFriendRemark(userIdAndInfo.get(user.getOrderUserId()).getFriendRemarks());
            mainMember.setInterests(interests);
            mainMember.setName(user.getName());
            mainMember.setGender(user.getGender());
            mainMember.setUid(user.getOrderUserId());
            mainMember.setLevel(userIdAndLevel.get(user.getOrderUserId()));
            mainMember.setIcon(userIdAndAvatarMap.get(user.getOrderUserId()));
            mainMember.setReplaceMembers(replaceMembers);
            retList.add(mainMember);
        }

        return retList;
    }

    public List<ResClubActivityMemberManage> buildClubActivityMemberManage(Integer uid,
                                                                           List<TbSignUser> tbSignUsers, Integer activityId, Integer clubId) {
        List<ResClubActivityMemberManage> items = Lists.newArrayList();

        List<Integer> userIds = Lists.newArrayList();
        for (TbSignUser user : tbSignUsers) {
            if (user.getOrderUserId() != null) {
                userIds.add(user.getOrderUserId());
            }
        }

        //批量查询用户信息
        APIResponse<List<RespUserInfoDetail>> respUserInfoBase = null;
        respUserInfoBase =
                userServiceFacade.batchQueryUserInfoDetail(uid, userIds);
        List<RespUserInfoDetail> respUserInfoBases = new ArrayList<RespUserInfoDetail>();
        if (respUserInfoBase.isRet()) {
            respUserInfoBases = respUserInfoBase.getData();
        } else {
            return null;
        }

        Map<Integer, String> userIdAndAvatarMap = Maps.newHashMap();
        for (RespUserInfoDetail userInfo : respUserInfoBases) {
            userIdAndAvatarMap.put(userInfo.getUid(), userInfo.getIcon());
        }
        //APP3.0需求 现场管理成员备注
        Map<Integer, RespUserInfoBase> userInfoMap = Maps.newHashMap();
        for (RespUserInfoDetail userInfo : respUserInfoBases) {
            userInfoMap.put(userInfo.getUid(), userInfo);
        }
        for (TbSignUser tbSignUser : tbSignUsers) {
            ResClubActivityMemberManage memberManage = new ResClubActivityMemberManage();
            memberManage.setClubId(clubId);
            memberManage.setActivityId(activityId);
            memberManage.setPayChannel(tbSignUser.getManageType().intValue() == 5 ? 1 : 0);
            memberManage.setManageType(tbSignUser.getManageType());
            memberManage.setGender(tbSignUser.getGender());
            String avatar = userIdAndAvatarMap.get(tbSignUser.getOrderUserId());
            memberManage.setAvatar(Strings.isNullOrEmpty(avatar) ? "" : avatar);
            memberManage.setMobile(tbSignUser.getMobile());
            memberManage.setName(tbSignUser.getName());
            memberManage.setSignUpType(tbSignUser.getIsReplace());
            memberManage.setUid(tbSignUser.getOrderUserId());
            memberManage.setOrderId(tbSignUser.getOrderId());
            memberManage.setSignId(tbSignUser.getId());
            if (null != userInfoMap.get(uid)) {
                if (null != userInfoMap.get(uid).getFriendRemarks() &&
                        !"".equals(userInfoMap.get(uid).getFriendRemarks())) {
                    memberManage.setRemarkname(
                            userInfoMap.get(uid).getFriendRemarks());
                }
            }

            items.add(memberManage);
        }

        List<ResClubActivityMemberManage> retList = Lists.newArrayList();

        for (ResClubActivityMemberManage mainMember : items) {
            if (mainMember.getSignUpType().intValue() == 1) {
                continue;//不是主要信息人
            }
            if (mainMember.getOrderId() != null) {
                List<ResClubActivityMemberManage> replaceMembers = Lists.newArrayList();
                for (ResClubActivityMemberManage replaceMember : items) {
                    if (replaceMember.getManageType().intValue() == 5) {
                        continue;//补报名人没有代报名
                    }
                    if (replaceMember.getSignUpType().intValue() != 1) {
                        continue;//不是代报名
                    }
                    if (replaceMember.getOrderId().intValue() != mainMember.getOrderId().intValue()) {
                        continue;
                    }
                    replaceMembers.add(replaceMember);
                }
                mainMember.setReplaceMembers(replaceMembers);
            }
            retList.add(mainMember);
        }

        return retList;
    }

    /**
     * 暂停活动
     * @param reqSuspendInfo
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse suspendActivity(ReqSuspendInfo reqSuspendInfo) {
        TbClubActivityExample tbClubActivityExample=new TbClubActivityExample();
        tbClubActivityExample.createCriteria().andActivityIdEqualTo(reqSuspendInfo.getActivityId()).andIsDeleteEqualTo((byte)0);
        List<TbClubActivity> tbClubActivityList=tbClubActivityMapper.selectByExample(tbClubActivityExample);

        if (CollectionUtils.isEmpty(tbClubActivityList)){
            return APIResponse.returnFail(ApiResponseEnum.RESOURCE_NOT_FOUND.getId(), "活动不存在");
        }
        TbClubActivity tbClubActivity=tbClubActivityList.get(0);
        if (!clubMemberService.isClubAdminMember(reqSuspendInfo.getUid(), tbClubActivity.getClubId())) {//校验只有管理员主席可以暂停
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED.getId(),"请先加入俱乐部并努力获取管理员权限。");
        }
        ActivityInfo info = activityOpenService.selectOneActivityById(reqSuspendInfo.getActivityId());
        if (!info.getStatus().equals(Constants.BYTE_ZERO)){//已暂停不可重复暂停
            return APIResponse.returnFail("该活动已取消或已暂停，不能暂停。");
        }
        if (!DateUtils.dateCompare(info.getEndTime(), new Date(), false)){//当前时间小于活动结束时间 可暂停
            return APIResponse.returnFail(ApiResponseEnum.RESOURCE_NOT_FOUND.getId(), "活动已结束，没有暂停的必要啦！");
        }
        info.setStatus(Constants.BYTE_ONE);
        ActivityInfo activityInfo = activityOpenService.updateTbActivity(info);
        if(null == activityInfo)
        {
            return APIResponse.returnFail(ApiResponseEnum.RESOURCE_NOT_FOUND.getId(), "活动不存在");
        }
        tbClubActivity.setActivityStatus(Constants.FLOAT_PAUSE);//设置为已暂停
        int count =tbClubActivityMapper.updateByExample(tbClubActivity,tbClubActivityExample);//更改活动状态为暂停
        if (count>0){//删除solr搜索条件
            ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
            APIResponse responseSolr=activitySearchService.deleteDocById(reqSuspendInfo.getActivityId());
            logger.info("----------暂停活动-从搜索引擎下架------"+JSON.toJSONString(responseSolr));

            clubSearchBizService.updateSignupActivityCountOfClubIndex(tbClubActivity.getClubId(), -1);
            logger.info("----------暂停活动-从俱乐部搜索引擎下架------");
        }
        return (count>0)?APIResponse.returnSuccess("暂停报名成功"):APIResponse.returnFail("暂停报名失败");
    }


    /**
     * 恢复暂停活动
     *
     * @param reqSuspendInfo
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse reSuspendActivity(ReqSuspendInfo reqSuspendInfo) {
        Integer activityId = reqSuspendInfo.getActivityId();
        TbClubActivityExample tbClubActivityExample = new TbClubActivityExample();
        tbClubActivityExample.createCriteria()
                .andActivityIdEqualTo(activityId)
                .andIsDeleteEqualTo((byte) 0);
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(tbClubActivityExample);

        if (CollectionUtils.isEmpty(tbClubActivityList)) {
            return APIResponse.returnFail("活动不存在");
        }
        TbClubActivity tbClubActivity = tbClubActivityList.get(0);
        if (!clubMemberService.isClubAdminMember(reqSuspendInfo.getUid(), tbClubActivity.getClubId())) {//校验只有管理员主席可以暂停
            return APIResponse.returnFail("请先加入俱乐部并努力获取管理员权限。");
        }
        ActivityInfo info = activityOpenService.selectOneActivityById(reqSuspendInfo.getActivityId());
        if (info.getStatus().equals(Constants.BYTE_ZERO)) {
            return APIResponse.returnFail("该活动已是正常报名状态，不需要恢复。");
        }
        float activityStatus = 0.0f;
        if (info.getEndTime().getTime() <= System.currentTimeMillis()) {
            activityStatus = 2f;
        } else {
            if (info.getSignEndTime().getTime() <= info.getStartTime().getTime()) {
                if (info.getStartTime().getTime() <= System.currentTimeMillis()) {
                    activityStatus = 1f;
                }
            } else {
                if (info.getSignEndTime().getTime() <= System.currentTimeMillis()) {
                    activityStatus = 1f;
                }
            }
        }
        tbClubActivity.setActivityStatus(activityStatus);
        logger.warn("更新活动状态为：" + activityStatus);
        tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);
        info.setStatus(Constants.BYTE_ZERO);
        ActivityInfo activityInfo = activityOpenService.updateTbActivity(info);
        if (null == activityInfo) {
            throw new BizException("恢复暂停活动失败：" + JSONObject.toJSONString(activityInfo));
        }
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        APIResponse<RespClubActivity> response = queryClubActivityById(activityId);
        RespClubActivity respClubActivity = response.getData();
        logger.info("----------恢复暂停的活动------");
        activitySupportService.addActivityIndex4Solr(respClubActivity);
        clubSearchBizService.updateSignupActivityCountOfClubIndex(tbClubActivity.getClubId(), 1);
        logger.info("----------从俱乐部索引恢复暂停的活动个数------");
        return APIResponse.returnSuccess("恢复正常报名成功");
    }

    /**
     * 取消活动 点击取消活动，判断是否超过活动结束时间 如果超过跳出提示不可取消， <p> 如果没超过跳出提示，是否取消活动，点是则取消活动， 退回所有报名人的款项 退款 记录流水
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse cancelActivity(Integer activityId, Integer uid, boolean isAdmin, int larkAppId) {
        APIResponse<RespClubActivity> apiResponse = queryClubActivityById(activityId, uid);
        RespClubActivity respClubActivity = apiResponse.getData();
        if (!clubMemberService.isClubAdminMember(uid, respClubActivity.getClubId())) {
            return APIResponse.returnFail("请先加入俱乐部并努力获取管理员权限。");
        }

        if (null == respClubActivity || respClubActivity.getIsDelete().equals((byte) 1)) {
            return APIResponse.returnFail("活动不存在！");
        }
        Date endTime = respClubActivity.getEndTime();
        if (!isAdmin && !DateUtils.dateCompare(endTime, new Date(), false)) {//当前时间小于活动结束时间 可取消
            return APIResponse.returnFail("活动已结束，不可取消！");
        }
        TbClubActivityExample example = new TbClubActivityExample();
        example.createCriteria().andActivityIdEqualTo(activityId)
                .andIsDeleteEqualTo(Constants.BYTE_ZERO);
        List<TbClubActivity> clubActivityList = tbClubActivityMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(clubActivityList)) {
            return APIResponse.returnFail("活动不存在!");
        }
        //先取消活动表的活动
        TbActivity updateActivity = new TbActivity();
        updateActivity.setId(activityId);
        updateActivity.setStatus(Constants.BYTE_TWO);
        updateActivity.setAlreadySignTotalNum(0);
        int updateCount = tbActivityMapper.updateByPrimaryKeySelective(updateActivity);
        if(updateCount <= 0) {
            throw new BizException("取消活动表活动失败");
        }
        //再取消俱乐部活动表的活动
        TbClubActivity tbClubActivity = clubActivityList.get(0);
        tbClubActivity.setActivityStatus(3f);
        int clubActivityCount = tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);
        if (clubActivityCount <= 0) {
            throw new BizException("取消活动失败");
        }
        //处理订单
        if (processRefundOrderActivity(respClubActivity, activityId, "活动发起人取消活动", null, (byte) 3,larkAppId)) {
            //删除solr索引
            ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
            activitySearchService.deleteDocById(activityId);
            //推送取消活动消息
            cppService.pushCancelActivity(respClubActivity,larkAppId);
            clubSearchBizService.updateSignupActivityCountOfClubIndex(respClubActivity.getClubId(), -1);
            return APIResponse.returnSuccess("取消活动成功!");
        }
        return APIResponse.returnFail("取消活动失败!");
    }

    /**
     * 处理订单退款
     */
    public boolean processRefundOrderActivity(RespClubActivity respClubActivity, Integer activityId, String reason,
                                              Integer uid, Byte refundType, int larkAppId) {
        //线上所有订单状态更改为创办人取消
        TbOrderExample orderExample = new TbOrderExample();
        TbOrderExample.Criteria orderCriteria = orderExample.createCriteria();
        orderCriteria.andActivityIdEqualTo(activityId);
        TbOrder o = new TbOrder();
        o.setCancelType((byte) 2);
        orderMapper.updateByExampleSelective(o, orderExample);

        //线上订单
        orderCriteria.andActivityIdEqualTo(activityId);
        if (null != uid) {
            orderCriteria.andOrderUidEqualTo(uid);
        }
        orderCriteria.andOrderStatusEqualTo(Constants.BYTE_TWO);//支付成功
        List<TbOrder> orderList = orderMapper.selectByExample(orderExample);

        if (CollectionUtils.isEmpty(orderList)) {
            return true;
        }

        try {
            for (TbOrder tbOrder : orderList) {
                logger.warn("订单取消退款，订单号：" + tbOrder.getOrderNo());


                //如果只有余额，则退俱乐部余额到线上账户
                if (tbOrder.getPayAmount().doubleValue() == 0
                        && tbOrder.getAccumulateAmount() == 0) {
                    logger.warn("没有第三方支付和鸟蛋支付，不调支付系统退款，直接退俱乐部抵扣余额");
                    //4. 更新订单状态
                    tbOrder.setOrderStatus((byte) 4); //退款中
                    tbOrder.setCancelType((byte) 2); //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消
                    orderMapper.updateByPrimaryKeySelective(tbOrder);

                    boolean isret = this.cancelOrderNotifyCallback(tbOrder.getOrderNo());
                    if (!isret) {
                        logger.warn("直接退俱乐部抵扣余额，失败");
                        throw new BizException("直接退俱乐部抵扣余额，失败");
                    }

                    //4. 更新订单状态
                    tbOrder.setOrderStatus((byte) 5); //退款完成
                    tbOrder.setCancelType((byte) 2); //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消
                    orderMapper.updateByPrimaryKeySelective(tbOrder);
                }
                cppService.pushCancelActivityToMember(respClubActivity, tbOrder.getOrderNo(), larkAppId);

                //2、退积分和第三方
                String refundOrderNo = CommonUtils.generateOrderNo(tbOrder.getOrderUid());
                if ((tbOrder.getAccumulateAmount() == null
                        || tbOrder.getAccumulateAmount().doubleValue() <= 0)
                        && (tbOrder.getPayAmount() == null
                        || tbOrder.getPayAmount().doubleValue() <= 0)) {

                    tbOrder.setCancelType((byte) 2);
                    orderMapper.updateByPrimaryKeySelective(tbOrder);
                } else {
                    APIRequest apiRequest = setRefundOrderParam(tbOrder, refundOrderNo, reason);//组装退款所需参数
                    logger.warn("调用支付系统退款：" + JSONObject.toJSONString(apiRequest));
                    APIResponse<RefundStatusEnum> enumAPIResponse = orderPayService.refundApply(apiRequest);//调用支付系统退款
                    if (enumAPIResponse.isRet()) {//申请退款成功
                        //退款申请记录
                        insertOrderRefund(
                                tbOrder.getPayAmount(),
                                tbOrder.getId(),
                                tbOrder.getPayType(),
                                tbOrder.getOrderUid(),
                                reason, refundType,
                                refundOrderNo);
                        //修改订单状态//1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价
                        //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消
                        tbOrder.setOrderStatus((byte) 4);
                        tbOrder.setCancelType((byte) 2);
                        orderMapper.updateByPrimaryKeySelective(tbOrder);
                    }
                }
            }
            return true;
        } catch (Exception e) {
            logger.warn("退款申请失败，活动编号：" + activityId);
            logger.warn(e.getMessage());
            return false;
        }
    }

    /**
     * 插入俱乐部成员线上账户流水
     */
    private TbClubOnlineMemberAccountStream insertClubOnlineMemberAccountStream(
            int uid,
            int productId,
            int clubId,
            int status,
            BigDecimal income,
            int payChannel,
            String remark,
            int type,
            BigDecimal preAmount,
            BigDecimal sufAmount,
            int clubOnlineMemberAccountId,
            String cheques,
            String drawee,
            String typeIntro) {

        TbClubOnlineMemberAccountStream clubOnlineMemberAccountStream = new TbClubOnlineMemberAccountStream();
        clubOnlineMemberAccountStream.setPreAmount(preAmount);
        clubOnlineMemberAccountStream.setSufAmount(sufAmount);
        clubOnlineMemberAccountStream.setProductId(productId);
        clubOnlineMemberAccountStream.setClubOnlineMemberAccountId(clubOnlineMemberAccountId);
        clubOnlineMemberAccountStream.setClubId(clubId);
        clubOnlineMemberAccountStream.setIncome(income);
        clubOnlineMemberAccountStream.setPayChannel((byte) payChannel);
        clubOnlineMemberAccountStream.setRemark(remark);
        clubOnlineMemberAccountStream.setSerialNo(NumberGenerator.getNextOrderNo());
        clubOnlineMemberAccountStream.setUid(uid);
        clubOnlineMemberAccountStream.setStatus((byte) status);
        clubOnlineMemberAccountStream.setType((byte) type);
        clubOnlineMemberAccountStream.setTypeIntro(typeIntro);
        //生成订单号
        clubOnlineMemberAccountStream.setOutTradeNo(NumberGenerator.getNextOrderNo());
        //收款方
        clubOnlineMemberAccountStream.setCheques(cheques);
        //付款方
        clubOnlineMemberAccountStream.setDrawee(drawee);

        if (payChannel == 1) {  //支付宝
            clubOnlineMemberAccountStream.setPayMode("支付宝充值");
        } else if (payChannel == 2) {  //微信支付
            clubOnlineMemberAccountStream.setPayMode("微信充值");
        }

        int n = clubOnlineMemberAccountStreamMapper.insertSelective(clubOnlineMemberAccountStream);
        if (n > 0) {
            return clubOnlineMemberAccountStream;
        } else {
            return null;
        }
    }

    /**
     * 补请假订单退款
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void supplementLeaveRefundOrder(Integer activityId, String reason,
                                           Integer uid, Byte refundType) {
        if (activityId == null || uid == null || refundType == null) {
            logger.warn("补请假退款失败, 失败原因: 参数异常, 用户id: "
                    + uid + "活动id: " + activityId + "退款类型: " + refundType);
            throw new BizException("补请假退款失败, 失败原因: 参数异常");
        }


        //0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消
        TbOrderExample orderExample = new TbOrderExample();
        TbOrderExample.Criteria orderCriteria = orderExample.createCriteria();
        orderCriteria.andActivityIdEqualTo(activityId);
        orderCriteria.andOrderUidEqualTo(uid);
        orderCriteria.andOrderStatusIn(Lists.<Byte>newArrayList(Constants.BYTE_TWO, (byte) 7));//支付成功
        List<TbOrder> orderList = orderMapper.selectByExample(orderExample);
        if (CollectionUtils.isEmpty(orderList)) {
            logger.warn("补请假退款失败, 失败原因: 订单查询不存在, 用户id: "
                    + uid + "活动id: " + activityId);
            throw new BizException("补请假退款失败, 失败原因: 订单查询不存在, 用户id: "
                    + uid + "活动id: " + activityId);
        }

        try {
            for (TbOrder tbOrder : orderList) {
                if ((tbOrder.getAccumulateAmount() == null
                        || tbOrder.getAccumulateAmount().doubleValue() <= 0)
                        && (tbOrder.getPayAmount() == null
                        || tbOrder.getPayAmount().doubleValue() <= 0)) {
                    continue;
                }

                logger.warn("补请假订单退款，订单号：" + tbOrder.getOrderNo());

                //修改订单状态 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价
                tbOrder.setOrderStatus((byte) 4);
                orderMapper.updateByPrimaryKeySelective(tbOrder);
                logger.warn("补请假订单状态改为退款中：" + JSONObject.toJSONString(tbOrder));
                String refundOrderNo = CommonUtils.generateOrderNo(tbOrder.getOrderUid());//退款单号
                logger.warn("开始插入退款申请：" + refundOrderNo);
                //退款申请记录
                boolean isSuccess = insertOrderRefund(
                        tbOrder.getPayAmount(),
                        tbOrder.getId(),
                        tbOrder.getPayType(),
                        tbOrder.getOrderUid(),
                        reason, refundType,
                        refundOrderNo);
                logger.warn("结束插入退款申请：" + JSONObject.toJSONString(isSuccess));

                if (!isSuccess) {
                    logger.warn("补请假: 申请积分退款和第三方退款失败, 失败原因: 插入退款申请记录失败");
                    throw new BizException("补请假退款失败, 退款申请记录失败");
                }

                //2、退积分和第三方
                APIRequest apiRequest =
                        setRefundOrderParam(tbOrder, refundOrderNo, reason);//组装退款所需参数
                APIResponse<RefundStatusEnum> enumAPIResponse =
                        orderPayService.refundApply(apiRequest);//调用支付系统退款

                if (!enumAPIResponse.isRet()) {//申请退款失败
                    logger.warn("补请假: 申请积分退款和第三方退款失败, 失败原因: "
                            + enumAPIResponse.getErrmsg());
                    throw new BizException("补请假: 申请积分退款和第三方退款失败");
                }
            }

        } catch (Exception e) {
            logger.warn("补请假退款申请失败，活动编号：" + activityId + ", 失败原因: " + e.getMessage());
            throw new BizException("补请假退款申请失败，活动编号：" + activityId);
        }
    }

    public int refundClubOnlineMemberAccount(TbOrder tbOrder) {
        TbClubOnlineMemberAccountExample memberAccountExample = new TbClubOnlineMemberAccountExample();
        TbClubOnlineMemberAccountExample.Criteria memberAccountCriteria = memberAccountExample.createCriteria();
        memberAccountCriteria.andUidEqualTo(tbOrder.getOrderUid());
        memberAccountCriteria.andIsDeleteEqualTo(Constants.BYTE_ZERO);
        List<TbClubOnlineMemberAccount> tbClubOnlineMemberAccountList = clubOnlineMemberAccountMapper.selectByExample(memberAccountExample);
        if (CollectionUtils.isNotEmpty(tbClubOnlineMemberAccountList)) {
            TbClubOnlineMemberAccount tbClubOnlineMemberAccount = tbClubOnlineMemberAccountList.get(0);
            BigDecimal moneyTotal = tbClubOnlineMemberAccount.getMoneyTotal();
            tbClubOnlineMemberAccount.setMoneyTotal(moneyTotal.add(tbOrder.getBalanceAmount()));
            int count = clubOnlineMemberAccountMapper.updateByPrimaryKeySelective(tbClubOnlineMemberAccount);
            return count;
        }
        return 0;
    }

    public int refundClubOnlineMemberAccount(Integer uid, BigDecimal feeTotal) {
        TbClubOnlineMemberAccountExample memberAccountExample = new TbClubOnlineMemberAccountExample();
        TbClubOnlineMemberAccountExample.Criteria memberAccountCriteria = memberAccountExample.createCriteria();
        memberAccountCriteria.andUidEqualTo(uid);
        memberAccountCriteria.andIsDeleteEqualTo(Constants.BYTE_ZERO);
        List<TbClubOnlineMemberAccount> tbClubOnlineMemberAccountList = clubOnlineMemberAccountMapper.selectByExample(memberAccountExample);
        if (CollectionUtils.isNotEmpty(tbClubOnlineMemberAccountList)) {
            TbClubOnlineMemberAccount tbClubOnlineMemberAccount = tbClubOnlineMemberAccountList.get(0);
            BigDecimal moneyTotal = tbClubOnlineMemberAccount.getMoneyTotal();
            tbClubOnlineMemberAccount.setMoneyTotal(moneyTotal.add(feeTotal));
            int count = clubOnlineMemberAccountMapper.updateByPrimaryKeySelective(tbClubOnlineMemberAccount);
            return count;
        }
        return 0;
    }

    public boolean insertOrderRefund(BigDecimal amount,
                                     Integer orderId,
                                     Byte payId,
                                     Integer uid,
                                     String reason, Byte refundType,
                                     String refundOrderNo) {
        TbOrderRefund tbOrderRefund = new TbOrderRefund();
        tbOrderRefund.setReason(reason);
        tbOrderRefund.setAmount(amount);
        tbOrderRefund.setRefundUid(uid);
        tbOrderRefund.setAudit((byte) 0);
        tbOrderRefund.setOrderId(orderId);
        tbOrderRefund.setPayId(payId);
        tbOrderRefund.setState((byte) 0);
        tbOrderRefund.setAudit((byte) 0);
        tbOrderRefund.setRefundType(refundType);
        tbOrderRefund.setRefundOrderNo(refundOrderNo);
        int count = orderRefundMapper.insertSelective(tbOrderRefund);

        if (count <= 0) {
            logger.warn("退款记录生成失败:" + JSONObject.toJSONString(tbOrderRefund));
            return false;
        }
        logger.warn("退款记录生成成功:" + JSONObject.toJSONString(tbOrderRefund));
        return true;
    }

    /**
     * 组装退款所需参数
     */
    public APIRequest setRefundOrderParam(TbOrder tbOrder,
                                          String refundOrderNo,
                                          String reason) {
        //支付信息 包含积分、第三方支付
        List<ReqRefundPayInfo> payInfoList = new ArrayList<>();

        if (tbOrder.getAccumulateAmount() != null
                && tbOrder.getAccumulateAmount().doubleValue() > 0) {
            ReqRefundPayInfo reqRefundAccumulateInfo = new ReqRefundPayInfo();
            reqRefundAccumulateInfo.setPayId(PayWayEnum.PAY_WAY_FOR_AGES.getPayId());
            reqRefundAccumulateInfo.setRefundAmount(BigDecimal.valueOf(tbOrder.getAccumulateAmount()));
            payInfoList.add(reqRefundAccumulateInfo);
        }

        if (tbOrder.getPayAmount() != null
                && tbOrder.getPayAmount().doubleValue() > 0) {
            ReqRefundPayInfo reqRefundPayInfo = new ReqRefundPayInfo();
            reqRefundPayInfo.setPayId(tbOrder.getPayType().intValue());
            reqRefundPayInfo.setRefundAmount(tbOrder.getPayAmount());
            payInfoList.add(reqRefundPayInfo);
        }

        //商品信息
        List<ReqRefundProduct> reqRefundProductList = new ArrayList<>();
        ReqRefundProduct reqRefundProduct = new ReqRefundProduct();
        reqRefundProduct.setProductId(tbOrder.getActivityId() + "");
        reqRefundProductList.add(reqRefundProduct);

        ReqOrderRefund reqOrderRefund = new ReqOrderRefund();
        reqOrderRefund.setOrderNo(tbOrder.getOrderTradeNo());
        reqOrderRefund.setNeedAudit(false);
        reqOrderRefund.setOutTradeNo(tbOrder.getOrderNo());
        reqOrderRefund.setOutTradeRefundNo(refundOrderNo);
        reqOrderRefund.setReason(reason);

        reqOrderRefund.setUid(tbOrder.getOrderUid());
        reqOrderRefund.setSourceBusinessId(Constants.CLUB_ACTIVITY_REFUND_ORDER_BUSINESS_CODE);
        reqOrderRefund.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
        reqOrderRefund.setReqRefundPayInfos(payInfoList);
        reqOrderRefund.setRefundProductList(reqRefundProductList);
        APIRequest apiRequest = new APIRequest();
        apiRequest.setData(reqOrderRefund);
        return apiRequest;
    }


    @Override
    public APIResponse<List<RespClubMember>> clubMemberAccountList(
            Integer userId, ReqClubMemberAccount reqClubMemberAccount) {

        List<RespClubMember> respClubMembers = clubMemberService.listClubMembers(userId,
                reqClubMemberAccount.getClubId(), true, true, 1, Integer.MAX_VALUE);

        if (CollectionUtils.isEmpty(respClubMembers)) {
            return APIResponse.returnFail("还没有成员加入");
        }

        List<Integer> userIds = Lists.newArrayList();
        for (RespClubMember respClubMember : respClubMembers) {
            userIds.add(respClubMember.getUid());
        }

        //批量查询用户信息
        APIResponse<List<RespUserInfoBase>> respUserInfoBase =
                userServiceFacade.batchQueryUserInfo(userIds);
        if (!respUserInfoBase.isRet()) {
            return APIResponse.returnFail("还没有成员加入");
        }

        Map<Integer, String> userIdAndMobileMap = Maps.newHashMap();
        List<RespUserInfoBase> respUserInfoBases = respUserInfoBase.getData();
        for (RespUserInfoBase userInfo : respUserInfoBases) {
            userIdAndMobileMap.put(userInfo.getUid(), userInfo.getMobile());
        }

        for (RespClubMember respClubMember : respClubMembers) {
            if (!Strings.isNullOrEmpty(respClubMember.getUsername())) {
                String indexChar = respClubMember.getUsername().charAt(0) + "";
                respClubMember.setIndexCharToUserName(indexChar);
                if (PinYinUtils.isChinese(indexChar)) {
                    String indexCharToUserName =
                            PinYinUtils.hanyuToPinyin(indexChar).charAt(0) + "";
                    respClubMember.setIndexCharToUserName(indexCharToUserName);
                }
            }
            respClubMember.setMobile(userIdAndMobileMap.get(respClubMember.getUid()));
        }

        return APIResponse.returnSuccess(respClubMembers);
    }

    @Override
    public APIResponse memberManageMendSignUp(Integer userId,
                                              ReqClubActivityMendSignUp reqClubActivityMendSignUp) {

        //现金补报名仅仅只是报名列表中增加，金额不改，因为是线下直接收取。
        //如果是会费补报名的话，直接从会费扣除，修改线上会费表以及记录流水
        if (reqClubActivityMendSignUp.getMendSignUpUserId() != null) {
            TbSignUserExample tbSignUserExample = new TbSignUserExample();
            tbSignUserExample.createCriteria().andOrderUserIdEqualTo(
                    reqClubActivityMendSignUp.getMendSignUpUserId()).
                    andActivityIdEqualTo(reqClubActivityMendSignUp.getActivityId()).
                    andIsCancelEqualTo(0).andStatusEqualTo(1);
            if (CollectionUtils.isNotEmpty(signUserMapper.selectByExample(tbSignUserExample))) {
                return APIResponse.returnFail("该成员已经报名过该活动了");
            }
        }

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(reqClubActivityMendSignUp.getActivityId());
        if (!activityAPIResponse.isRet()) {
            return activityAPIResponse;
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        if (respClubActivity.getIsSettle().intValue() == 1) {
            return APIResponse.returnFail("活动已经结算，不能报名");
        }

        /*if (respClubActivity.getEndTime().getTime() < new Date().getTime()) {
            return APIResponse.returnFail("活动已经结束，不能报名");
        }*/

        if (respClubActivity.getStatus().intValue() == 2) {
            return APIResponse.returnFail("活动已取消，不能报名");
        }

        TbSignUser tbSignUser = new TbSignUser();
        tbSignUser.setName(reqClubActivityMendSignUp.getName());
        tbSignUser.setMobile(reqClubActivityMendSignUp.getMobile());
        tbSignUser.setActivityId(reqClubActivityMendSignUp.getActivityId());
        if (reqClubActivityMendSignUp.getGender() == null
                || reqClubActivityMendSignUp.getGender().intValue() == 0) {
            reqClubActivityMendSignUp.setGender(1);
        }
        tbSignUser.setGender(reqClubActivityMendSignUp.getGender());
        tbSignUser.setIsCancel(0);
        tbSignUser.setIsReplace(0);
        tbSignUser.setManageType(5); //补报名
        if (reqClubActivityMendSignUp.getSignFee() == null
                || reqClubActivityMendSignUp.getSignFee().doubleValue() <= 0) {
            reqClubActivityMendSignUp.setSignFee(new BigDecimal(0));
        }
        tbSignUser.setMendSignUpAmount(reqClubActivityMendSignUp.getSignFee());
        if (reqClubActivityMendSignUp.getPayType() == 1) {
            tbSignUser.setPayChannel(1);//现金
        } else {
            tbSignUser.setPayChannel(0);//会费
            //APP3.0需求会费支付时直接扣除成员线上会费
            //TODO 调测日志
            logger.warn("3.0 补报名报名功能调测日志。。。");
            BigDecimal fee = reqClubActivityMendSignUp.getSignFee();
            if (fee != null && fee.doubleValue() > 0) {
                ClubMemberAccountStreamInfo clubMemberAccountStreamInfo =
                        clubAccountService.addOrDeductionPersonClubAccountBalance(
                                fee, userId,
                                respClubActivity.getClubId(), false);
                if (clubMemberAccountStreamInfo == null) {
                    return APIResponse.returnFail("俱乐部余额不足抵扣");
                }
                //记录个人账户流水
                logger.warn("3.0 调测日志-扣除个人线上会费账户金额");
                clubAccountService.recordPersonClubAccountDeductibleStream(
                        userId,
                        reqClubActivityMendSignUp.getActivityId(),
                        respClubActivity.getName() + "会费补报名",
                        Constants.BYTE_ZERO,
                        respClubActivity.getClubId(), clubMemberAccountStreamInfo,
                        null, Constants.BYTE_ONE, Constants.BYTE_ONE);
            }
        }
        tbSignUser.setStatus(1);
        if (reqClubActivityMendSignUp.getMendSignUpUserId() != null) {
            tbSignUser.setOrderUserId(reqClubActivityMendSignUp.getMendSignUpUserId());
        }
        tbSignUser.setCreateTime(new Date());
        signUserMapper.insertSelective(tbSignUser);

        return APIResponse.returnSuccess();
    }

    /**
     * 现场管理提交
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse memberManagerSubmit(Integer userId,//当前登录用户,管理员身份
                                           List<ResClubActivityMemberManage>
                                                   resClubActivityMemberManages) {
        Integer activityId = resClubActivityMemberManages.get(0).getActivityId();
        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(activityId);
        if (!activityAPIResponse.isRet()) {
            return APIResponse.returnFail("活动不存在");
        }
        if (!clubMemberService.isClubAdminMember(userId, resClubActivityMemberManages.get(0).getClubId())) {
            return APIResponse.returnFail("请先加入俱乐部并努力获取管理员权限。");
        }
        Integer settleStatus = activityAPIResponse.getData().getIsSettle();
        if (settleStatus.intValue() == 1) {
            return APIResponse.returnFail("活动已经结算");
        }

        for (ResClubActivityMemberManage member : resClubActivityMemberManages) {
            TbSignUserExample signUserExample = new TbSignUserExample();
            TbSignUserExample.Criteria criteria = signUserExample.createCriteria();
            if (member.getSignId() != null && member.getSignId() > 0) {
                criteria.andIdEqualTo(member.getSignId())
                        .andActivityIdEqualTo(activityId)
                        .andStatusNotEqualTo(-1);
            } else {
                criteria.andActivityIdEqualTo(activityId).andStatusNotEqualTo(-1); //排除未支付
                if (null != member.getMobile()) {
                    criteria.andMobileEqualTo(member.getMobile());
                }
                criteria.andNameEqualTo(member.getName());
            }

            if (member.getManageType().intValue() == 5) {
                criteria.andManageTypeEqualTo(5);//补报名
            }
            if (member.getUid() != null && member.getUid() > 0) {
                criteria.andOrderUserIdEqualTo(member.getUid());
            }
            if (member.getOrderId() != null && member.getOrderId() > 0) {
                criteria.andOrderIdEqualTo(member.getOrderId());
            }
            List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(signUserExample);
            if (CollectionUtils.isEmpty(tbSignUsers)) {
                return APIResponse.returnFail("用户为: " + member.getName() + "，没有报名活动");
            }

            TbSignUser tbSignUser = tbSignUsers.get(0);
            tbSignUser.setManageType(member.getManageType());
            signUserMapper.updateByPrimaryKeySelective(tbSignUser);
        }

        TbClubActivityExample example = new TbClubActivityExample();
        example.createCriteria().andActivityIdEqualTo(activityId);
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(example);
        TbClubActivity tbClubActivity = tbClubActivityList.get(0);
        tbClubActivity.setIsSettle((byte) 2);
        tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);

        return APIResponse.returnSuccess();
    }

    @Override
    public APIResponse<Map<String, Object>> settlementDetailList(
            Integer uid, ReqClubActivityInfo reqClubActivityInfo) {
        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(reqClubActivityInfo.getActivityId());
        if (!activityAPIResponse.isRet()) {
            return APIResponse.returnFail("活动不存在");
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();

        if (respClubActivity.getEndTime().getTime() > System.currentTimeMillis()) {
            return APIResponse.returnFail("活动还未结束！");
        }

        APIResponse<List<TbSignUser>> responseTbSignUserInfo =
                getActivitySettlementSignUpInfo(reqClubActivityInfo);
        if (!responseTbSignUserInfo.isRet()) {
            return APIResponse.returnFail(responseTbSignUserInfo.getErrmsg());
        }

        Map<String, Object> retMap = Maps.newHashMapWithExpectedSize(2);
        Integer settleStatus = respClubActivity.getIsSettle();
        switch (settleStatus.intValue()) {
            case 0: //活动未结算
                retMap.put("settleStatus", 0);
                break;
            case 1: //活动已结算
                retMap.put("settleStatus", 1);
                break;
            case 2: //活动现场管理已提交(未结算)
                retMap.put("settleStatus", 2);
                break;
            default:
                break;
        }

        List<TbSignUser> tbSignUsers = responseTbSignUserInfo.getData();

        List<RespSettlementDetail> respSettlementDetails = buildRespSettlementDetail(uid, tbSignUsers);
        BigDecimal totalAmount = BigDecimal.ZERO;
        int totalCount = 0;
        for (RespSettlementDetail detail : respSettlementDetails) {
            if (detail.getManagerType() == 2) {
                totalCount += (detail.getFemaleNum() + detail.getMaleNum());
            } else if (detail.getManagerType() == 1 ||
                    detail.getManagerType() == 3 ||
                    detail.getManagerType() == 4) {
                totalAmount = totalAmount.add(detail.getDealAmount());
            }
        }
        retMap.put("totalAmount", totalAmount);
        retMap.put("totalCount", totalCount);
        retMap.put("settlementDetails", respSettlementDetails);


        return APIResponse.returnSuccess(retMap);
    }

    private APIResponse<List<TbSignUser>> getActivitySettlementSignUpInfo(
            ReqClubActivityInfo reqClubActivityInfo) {
        TbSignUserExample tbSignUserExample = new TbSignUserExample();
        TbSignUserExample.Criteria criteria = tbSignUserExample.createCriteria();
        criteria.andActivityIdEqualTo(
                reqClubActivityInfo.getActivityId())
                .andStatusEqualTo(1)
                .andManageTypeNotEqualTo(1);
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(tbSignUserExample);
        if (CollectionUtils.isEmpty(tbSignUsers)) {
            return APIResponse.returnFail("暂无数据");
        }
        return APIResponse.returnSuccess(tbSignUsers);
    }

    private List<RespSettlementDetail> buildRespSettlementDetail(Integer uid, List<TbSignUser> tbSignUsers) {
        List<RespSettlementDetail> respSettlementDetails = Lists.newArrayList();
        List<Integer> userIds = Lists.newArrayList();
        for (TbSignUser user : tbSignUsers) {
            if (user.getOrderUserId() != null) {
                userIds.add(user.getOrderUserId());
            }
        }
        //批量查询用户信息
        APIResponse<List<RespUserInfoDetail>> respUserInfoBase = null;
        respUserInfoBase = userServiceFacade.batchQueryUserInfoDetail(uid, userIds);
        List<RespUserInfoDetail> respUserInfoBases = new ArrayList<RespUserInfoDetail>();
        if (respUserInfoBase.isRet()) {
            respUserInfoBases = respUserInfoBase.getData();
        } else {
            return null;
        }

        Map<Integer, RespUserInfoBase> userIdAndAvatarMap = Maps.newHashMap();
        for (RespUserInfoBase userInfo : respUserInfoBases) {
            userIdAndAvatarMap.put(userInfo.getUid(), userInfo);
        }

        for (TbSignUser mainSignUser : tbSignUsers) {
            if (mainSignUser.getIsReplace().intValue() != 0) {
                //不是主要信息人
                continue;
            }

            int manCount = 0;
            int womenCount = 0;
            for (TbSignUser replaceSignUser : tbSignUsers) {

                if (replaceSignUser.getOrderId() == null
                        || mainSignUser.getOrderId() == null) {
                    continue;//补报名人没有订单
                }

                if (replaceSignUser.getOrderId().intValue()
                        != mainSignUser.getOrderId().intValue()) {
                    continue;
                }

                if (replaceSignUser.getGender().intValue() == 1) {
                    manCount++;
                }
                if (replaceSignUser.getGender().intValue() == 2) {
                    womenCount++;
                }
            }

            RespSettlementDetail respSettlementDetail = new RespSettlementDetail();
            respSettlementDetail.setUid(
                    mainSignUser.getOrderUserId() == null ? null : mainSignUser.getOrderUserId());
            respSettlementDetail.setName(mainSignUser.getName());

            if (mainSignUser.getOrderUserId() != null) {
                respSettlementDetail.setAvatar(
                        userIdAndAvatarMap.get(mainSignUser.getOrderUserId()).getIcon());
                respSettlementDetail.setRemarkname(
                        userIdAndAvatarMap.get(mainSignUser.getOrderUserId()).getFriendRemarks());
            } else {
                respSettlementDetail.setAvatar("");
            }

            if (mainSignUser.getOrderId() == null
                    && mainSignUser.getManageType().intValue() == 5) {
                //补报名用户
                if (mainSignUser.getGender().intValue() == 1) { //1男2女
                    respSettlementDetail.setMaleNum(1);
                    respSettlementDetail.setFemaleNum(0);
                } else if (mainSignUser.getGender().intValue() == 2) {
                    respSettlementDetail.setFemaleNum(1);
                    respSettlementDetail.setMaleNum(0);
                }

            } else {
                respSettlementDetail.setMaleNum(manCount);
                respSettlementDetail.setFemaleNum(womenCount);
            }
            respSettlementDetail.setManagerType(mainSignUser.getManageType().intValue());
            if (mainSignUser.getManageType().intValue() == 1 //请假 补请假 补报名 用户
                    || mainSignUser.getManageType().intValue() == 2
                    || mainSignUser.getManageType().intValue() == 5) {
                respSettlementDetail.setBalanceAmount(new BigDecimal(0));//俱乐部余额抵扣
                respSettlementDetail.setAccumulateAmount(new BigDecimal(0)); //鸟蛋抵扣
                respSettlementDetail.setDealAmount(new BigDecimal(0));//应付金额(总金额)
                respSettlementDetail.setOnlinePay(new BigDecimal(0));
                if (mainSignUser.getManageType().intValue() == 5) {
                    respSettlementDetail.setOffLinePay(mainSignUser.getMendSignUpAmount());//线下金额
                } else {
                    respSettlementDetail.setOffLinePay(new BigDecimal(0));
                }
            }

            if (mainSignUser.getOrderId() != null) {
                TbOrder tbOrder = orderMapper.selectByPrimaryKey(mainSignUser.getOrderId());
                if (tbOrder != null) {
                    if (tbOrder.getOrderStatus().equals(Constants.BYTE_ONE)) {
                        continue;
                    }
                    respSettlementDetail.setBalanceAmount(tbOrder.getBalanceAmount());//俱乐部余额抵扣
                    respSettlementDetail.setAccumulateAmount(
                            new BigDecimal(tbOrder.getAccumulateAmount())); //鸟蛋抵扣
                    respSettlementDetail.setDealAmount(tbOrder.getOrderAmount());//应付金额(总金额)
                    respSettlementDetail.setOnlinePay(tbOrder.getPayAmount()); //线上金额
                    respSettlementDetail.setOffLinePay(new BigDecimal(0));//线下支付为0
                }
            }
            respSettlementDetails.add(respSettlementDetail);
        }

        return respSettlementDetails;
    }

    /**
     * 用户自己取消订单，申请取消，通知支付系统退款
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse cancelOrderNotify(Integer uid, String businessOrderNo, Integer cancelType, String reason) {
        //1. 查询订单信息
        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria().andOrderNoEqualTo(businessOrderNo);
        List<TbOrder> orders = orderMapper.selectByExample(orderExample);
        if (orders == null || orders.size() <= 0) {
            return APIResponse.returnFail("订单不存在");
        }
        TbOrder order = orders.get(0);
        if (uid.intValue() != order.getOrderUid()) {
            return APIResponse.returnFail("你没有对这个订单的操作权限。");
        }
        if(!order.getOrderStatus().equals(Constants.BYTE_TWO)
                && !order.getCancelType().equals(Constants.BYTE_ZERO))
        {
            return APIResponse.returnFail("订单已取消，不能退款了。");
        }
        updateSignUpUser(order);        //更新报名状态

        //2. 判断是否可以取消此订单
        TbClubActivityExample clubActivityExample = new TbClubActivityExample();
        clubActivityExample.createCriteria()
                .andActivityIdEqualTo(order.getActivityId()).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubActivity> clubActivities = tbClubActivityMapper.selectByExample(clubActivityExample);
        if (clubActivities == null || clubActivities.size() <= 0) {
            throw new BizException("俱乐部活动不存在");
        }
        TbClubActivity clubActivity = clubActivities.get(0);
        if (clubActivity.getIsCancelSignUp() == Constants.IS_YES) {
            throw new BizException("不可取消报名");   //不可取消报名
        }
        if (clubActivity.getIsSettle() == Constants.IS_YES) {
            throw new BizException("活动已经结算");   //活动已经结算
        }
        ActivityInfo activityInfo = activityOpenService.selectOneActivityById(clubActivity.getActivityId());
        Date activityStartTime = activityInfo.getStartTime(); //活动开始时间
        Byte limitTime = clubActivity.getCancelTimeLimit();   //活动开始前，可取消限制时间，单位：小时
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(activityStartTime);
        calendar.add(Calendar.HOUR_OF_DAY, -1 * limitTime);
        if (!(new Date().before(calendar.getTime()))) {     //当前时间不在可取消的时间范围内
            throw new BizException("当前时间不在可取消的时间范围内");
        }

        // 恢复库存
        Integer activityId = order.getActivityId();
        Integer orderId = order.getId();
        //3. 恢复报名人数库存
        TbSignUserExample signUserExample = new TbSignUserExample();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(activityId) //活动id
                .andOrderIdEqualTo(orderId)
                .andStatusEqualTo((int) Constants.BYTE_ONE);        //有效的
        List<TbSignUser> signUsers = signUserMapper.selectByExample(signUserExample);
        logger.warn("取消人数：" + JSON.toJSONString(signUsers));
        //计算要取消的男女报名人数
        int manCount = 0, femaleCount = 0;
        for (TbSignUser signUser : signUsers) {
            if (signUser.getGender() == Constants.BYTE_ONE) {
                manCount++;
            }
            if (signUser.getGender() == Constants.BYTE_TWO) {
                femaleCount++;
            }
        }

        logger.warn("更新活动已报名人数，activityId:" + activityId);
        Map<String, Object> paraMap = Maps.newHashMap();
        //更新活动已经报名的有效人数
        try {
            signUserExample.clear();
            signUserExample.createCriteria()
                    .andActivityIdEqualTo(activityId) //活动id
                    .andOrderIdEqualTo(orderId)
                    .andStatusEqualTo((int) Constants.BYTE_ZERO);        //有效的
            List<TbSignUser> counts = signUserMapper.selectByExample(signUserExample);
            paraMap.put("activityId", activityId);
            int minusCount = (0 - counts.size());
            if (minusCount > 0) {
                minusCount = 0;
            }
            //从活动报名人数库存中减去取消的男女人数
            APIResponse recoveryRes = recoverySignUpNum(
                    activityInfo.getLimitNum(), order.getActivityId(), counts.size(), femaleCount, 0); //取消
            logger.warn("3 恢复报名人数库存，男：" + counts.size() + ", 女：" + femaleCount + ", 返回：" + JSON.toJSONString(recoveryRes));
            if (!recoveryRes.isRet()) {
                logger.warn("恢复报名人库存异常：" + JSON.toJSONString(recoveryRes));
                throw new BizException("退款失败，请联系客服。");
            }
            logger.warn("更新报名人数完成, minusCount" + minusCount);
        } catch (RpcException rpe) {
            throw new BizException("调用活动模块失败" + JSON.toJSONString(paraMap));
        }
        //4. 更新报名人报名记录表
        signUserExample.clear();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(activityId)
                .andOrderIdEqualTo(order.getId());
        TbSignUser updateSignUser = new TbSignUser();
        updateSignUser.setManageType((int) Constants.BYTE_ONE);      //请假（用户取消）
        updateSignUser.setIsCancel((int) Constants.BYTE_ONE);        //取消
        updateSignUser.setStatus(Constants.ZERO);                   //0 无效(is_cancel为取消状态时)
        int uret = signUserMapper.updateByExampleSelective(updateSignUser, signUserExample);
        logger.warn("4 更新报名人报名记录表，更新为{}，返回：{}", JSON.toJSON(updateSignUser), uret);
        if (uret < 0) {
            throw new BizException(" 更新报名人报名记录表失败！");
        }

        String refundOrderNo = CommonUtils.generateOrderNo(uid);//退款单号

        //3. 退款
        //记录退款痕迹
        //取消类型 '0 未取消,  取消对象: 1 用户主动取消已支付订单(退款) 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消 5用户取消未支付订单',
        byte refundType = -1;
        if (cancelType == 1) {
            refundType = 2;
        }
        if (cancelType == 4) {
            refundType = 4;
        }

        //1: 活动结算AA退款 2:用户取消已支付订单退款 3:活动发起人取消已支付订单退款 4:活动未达到开启条件,给已经报名支付成功的人退款 5现场管理人补请假退款
        this.insertOrderRefund(
                order.getPayAmount(),
                order.getId(),
                order.getPayType(),
                order.getOrderUid(), reason,
                refundType, refundOrderNo);
        logger.warn("订单：" + order.getOrderNo() + ", 退款：第三方支付" + order.getPayAmount().doubleValue() + ", 俱乐部余额抵扣" + order.getBalanceAmount().doubleValue() + ", 鸟蛋抵扣" + order.getAccumulateAmount());
        //3.1 没有第三方支付和鸟蛋支付，不调支付系统退款，直接退俱乐部抵扣余额
        if (order.getPayAmount().doubleValue() == 0
                && order.getAccumulateAmount() == 0) {
            logger.warn("没有第三方支付和鸟蛋支付，不调支付系统退款，直接退俱乐部抵扣余额");
            //4. 更新订单状态
            order.setOrderStatus((byte) 4); //退款中
            order.setCancelType(cancelType.byteValue()); //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消
            orderMapper.updateByPrimaryKeySelective(order);

            boolean isret = this.cancelOrderNotifyCallback(order.getOrderNo());
            if (!isret) {
                logger.warn("直接退俱乐部抵扣余额，失败");
                throw new BizException("直接退俱乐部抵扣余额，失败");
            }

            //4. 更新订单状态
            order.setOrderStatus((byte) 5); //退款完成
            order.setCancelType(cancelType.byteValue()); //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消
            orderMapper.updateByPrimaryKeySelective(order);
        } else {
            //3.2 调用支付系统，申请退款
            APIRequest<ReqOrderRefund> refundRequest = new APIRequest<>();
            ReqOrderRefund reqOrderRefund = new ReqOrderRefund();
            reqOrderRefund.setNeedAudit(false);     //无需审核
            reqOrderRefund.setUid(uid);             //申请退款人uid
            reqOrderRefund.setSourceBusinessId(Constants.CLUB_ACTIVITY_ORDER_BUSINESS_CODE);   //业务id
            reqOrderRefund.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
            reqOrderRefund.setOrderNo(order.getOrderTradeNo());             //订单系统订单号
            reqOrderRefund.setOutTradeNo(order.getOrderNo());               //业务系统订单号
            reqOrderRefund.setOutTradeRefundNo(refundOrderNo);         //退款订单号，目前为活动的订单号
            if (reason != null) {
                reqOrderRefund.setReason(reason);
            } else {
                reqOrderRefund.setReason(order.getInfo());  //取消原因
            }
            List<ReqRefundPayInfo> reqRefundPayInfoList = new ArrayList<>();

            if (order.getPayAmount().doubleValue() != 0) {
                ReqRefundPayInfo rmb = new ReqRefundPayInfo();
                int type = order.getPayType();
                switch (type) {
                    case ClubConstants.PAY_TYPE_ALIPAY:
                        rmb.setPayId(PayWayEnum.PAY_WAY_ALIPAY.getPayId());
                        break;
                    case ClubConstants.PAY_TYPE_WEICHAT:
                        rmb.setPayId(PayWayEnum.PAY_WAY_WEICHAT.getPayId());
                        break;
                    case ClubConstants.PAY_TYPE_WAY_WEICHATH5:
                        rmb.setPayId(PayWayEnum.PAY_WAY_WEICHATH5.getPayId());
                        break;
                    case ClubConstants.PAY_TYPE_APPLYPAY:
                        rmb.setPayId(PayWayEnum.PAY_WAY_APPLE_PAY.getPayId());
                        break;
                    case ClubConstants.PAY_TYPE_UNIONPAY:
                        rmb.setPayId(PayWayEnum.PAY_WAY_UNION_PAY.getPayId());
                        break;
                    case ClubConstants.PAY_TYPE_FOR_ALIWEB:
                        rmb.setPayId(PayWayEnum.PAY_WAY_ALIPAY_H5.getPayId());
                        break;
                }
                rmb.setRefundAmount(order.getPayAmount());     //退回应支付费用
                reqRefundPayInfoList.add(rmb);
            }

            if (order.getAccumulateAmount() > 0) {        //如果鸟蛋为0，或小数，支付系统不予退回。
                ReqRefundPayInfo ages = new ReqRefundPayInfo();
                ages.setPayId(PayWayEnum.PAY_WAY_FOR_AGES.getPayId());
                ages.setRefundAmount(new BigDecimal(order.getAccumulateAmount())); //退回抵扣的鸟蛋数
                reqRefundPayInfoList.add(ages);
            }
            reqOrderRefund.setReqRefundPayInfos(reqRefundPayInfoList);

            List<ReqRefundProduct> reqRefundProducts = new ArrayList<>();
            ReqRefundProduct refundProduct = new ReqRefundProduct();
            refundProduct.setPrice(order.getOrderAmount());
            refundProduct.setProductId(String.valueOf(order.getActivityId()));
            refundProduct.setQuantity(1);
            refundProduct.setProductName("");
            reqRefundProducts.add(refundProduct);
            reqOrderRefund.setRefundProductList(reqRefundProducts);

            refundRequest.setData(reqOrderRefund);
            //4. 更新订单状态
            order.setOrderStatus((byte) 4); //退款中
            order.setCancelType(cancelType.byteValue()); //0 未取消,  取消对象: 1 用户主动取消 2活动创办人取消 3活动异常百灵鸟官方后台管理员取消 4活动未达到开启条件而取消
            orderMapper.updateByPrimaryKeySelective(order);

            logger.warn("开始调用支付系统退款：" + JSONObject.toJSONString(refundRequest));
            APIResponse<RefundStatusEnum> response = orderPayService.refundApply(refundRequest);
            logger.warn("调用支付系统退款，返回：" + JSON.toJSON(response));
            if (!response.isRet()) {
                throw new BizException("调用支付系统退款失败！");       //退款失败
            }
        }

        return APIResponse.returnSuccess();
    }

    /**
     * 用户取消订单，更改此用户和他代报名的用户报名记录状态
     */
    @Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED)
    public void updateSignUpUser(TbOrder order) {
        TbSignUserExample example = new TbSignUserExample();
        example.createCriteria()
                .andOrderIdEqualTo(order.getId())
                .andActivityIdEqualTo(order.getActivityId());
        TbSignUser signUser = new TbSignUser();
        signUser.setManageType(1);  //用户取消
        signUser.setIsCancel(1);    //报名取消
        signUser.setStatus(0);      //状态:  -1 下单超时未支付 0 无效(is_cancel为取消状态时,只有支付成功的订单被取消才会有此状态) 1 有效
        signUserMapper.updateByExampleSelective(signUser, example);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean cancelActivityOrderAdminCallback(RefundNotifyMsg refundNotifyMsg) {
        //查询是否有退款订单
        TbOrderRefundExample tbOrderRefundExample = new TbOrderRefundExample();
        TbOrderRefundExample.Criteria criteria = tbOrderRefundExample.createCriteria();
        criteria.andRefundOrderNoEqualTo(refundNotifyMsg.getOutTradeRefundOrderNo());
        List<TbOrderRefund> list = orderRefundMapper.selectByExample(tbOrderRefundExample);
        OrderCallBackMsg orderCallBackMsg = new OrderCallBackMsg();
        orderCallBackMsg.setOrderNo(refundNotifyMsg.getOutTradeNo());
        orderCallBackMsg.setType(OrderCallBackMsg.REFUND);
        if (null == list || list.size() == 0) {
            logger.error("该管理员取消活动退款订单消息回调, 退款订单不存在, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo()
                    + ", 订单系统订单号: " + refundNotifyMsg.getOrderNo());
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return false;
        }
        TbOrderRefund tbOrderRefund = list.get(0);
        //根据退款单中的订单号查询报名的用户
        TbSignUserExample userExample = new TbSignUserExample();
        TbSignUserExample.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andOrderIdEqualTo(tbOrderRefund.getOrderId()).andIsCancelEqualTo(0);
        List<TbSignUser> users = signUserMapper.selectByExample(userExample);
        if (null == users || users.size() == 0) {
            logger.error("该管理员取消活动退款订单消息回调, 下订单的用户不存在, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo()
                    + ", 订单系统订单号: " + refundNotifyMsg.getOrderNo()
                    + ", 退款订单号: " + refundNotifyMsg.getOutTradeRefundOrderNo());
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return false;
        }
        //将所有对应的报名用户都设置订单正常取消并退款
        TbSignUser user = new TbSignUser();
        user.setIsCancel(1);
        if (null != users.get(0).getStatus() && users.get(0).getStatus() == 1) {
            user.setStatus(0);
        }
        signUserMapper.updateByExampleSelective(user, userExample);
        TbOrder tbOrder = orderMapper.selectByPrimaryKey(tbOrderRefund.getOrderId());
        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId(), null);
        if (!activityAPIResponse.isRet()) {
            throw new BizException("查询俱乐部活动失败！" + JSON.toJSON(activityAPIResponse));
        }
        RespClubActivity respClubActivity = activityAPIResponse.getData();
        //退余额抵扣部分
        refundBalanceAmount(tbOrder, respClubActivity.getName(), respClubActivity.getClubId());
        tbOrder.setOrderStatus((byte) 5);//设置为退款成功
        tbOrder.setUpdateTime(null);
        orderMapper.updateByPrimaryKeySelective(tbOrder);
        orderCallBackMsg.setState(OrderCallBackMsg.SUCCESS);
        feedbackOrderSystemOrderStatus(orderCallBackMsg);
        return true;
    }

    /**
     * 支付系统退款后，通过MQ发送退款处理结果通知，收到通知后处理订单状态
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean cancelOrderNotifyCallback(String businessOrderNo) {
        //1. 查询订单信息，俱乐部活动信息
        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria()
                .andOrderNoEqualTo(businessOrderNo)
                .andOrderStatusEqualTo((byte) 4);    //取消，退款中的订单
        List<TbOrder> orders = orderMapper.selectByExample(orderExample);
        if (orders == null || orders.size() <= 0) {
            return false;
        }
        TbOrder order = orders.get(0);
        int activityId = order.getActivityId();
        int orderUid = order.getOrderUid();
        logger.warn("1 要更新状态的订单：" + JSON.toJSONString(order));

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(order.getActivityId(), null);
        if (!activityAPIResponse.isRet()) {
            throw new BizException("查询俱乐部活动失败！" + JSON.toJSON(activityAPIResponse));
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        int clubId = respClubActivity.getClubId();

        //2. 将抵扣的俱乐部余额退回到俱乐部成员账户
        refundBalanceAmount(order, respClubActivity.getName(), clubId);
        //5. 更改订单状态
        order.setOrderStatus((byte) 5); //用户取消，退款完成
        int ret = orderMapper.updateByPrimaryKeySelective(order);
        logger.warn("5  更改订单状态为5（已退款），返回：" + ret);
        //6.将此人剔除活动聊天组
        if (ret == Constants.IS_YES) {
            boolean result = cppService.addOrDelIMGroupMember(respClubActivity.getUid(),
                    activityId, respClubActivity.getGroupId(),
                    Lists.newArrayList(order.getOrderUid()), false);
            logger.warn("6 将此人{}剔除活动聊天组{}，返回：{}", order.getOrderUid(), respClubActivity.getGroupId(), result);
            cppService.pushCancelActivityOrder(respClubActivity, orderUid, order.getId());
            cppService.pushRefundActivityOrder(respClubActivity, orderUid, businessOrderNo);
            return true;
        }
        return false;
    }


    /**
     * 支付系统退款后，通过MQ发送退款处理结果通知，收到通知后处理订单状态(百灵鸟官方后台管理员退款)
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean cancelOrderNotifyCallbackAdmin(String businessOrderNo) {

        //1. 查询订单信息，俱乐部活动信息
        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria()
                .andOrderNoEqualTo(businessOrderNo)
                .andOrderStatusEqualTo((byte) 4);    //取消，退款中的订单
        List<TbOrder> orders = orderMapper.selectByExample(orderExample);
        if (orders == null || orders.size() <= 0) {
            return false;
        }
        TbOrder order = orders.get(0);
        int activityId = order.getActivityId();
        int orderUid = order.getOrderUid();
        logger.warn("1 要更新状态的订单：" + JSON.toJSONString(order));

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(order.getActivityId(), null);
        if (!activityAPIResponse.isRet()) {
            throw new BizException("查询俱乐部活动失败！" + JSON.toJSON(activityAPIResponse));
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        int clubId = respClubActivity.getClubId();

        //2. 将抵扣的俱乐部余额退回到俱乐部成员账户
        refundBalanceAmount(order, respClubActivity.getName(), clubId);
        //5. 更改订单状态
        order.setOrderStatus((byte) 3); //百灵鸟官方后台管理员取消
        int ret = orderMapper.updateByPrimaryKeySelective(order);
        logger.warn("3  更改订单状态为3（已退款），返回：" + ret);

        //6.将此人剔除活动聊天组
        if (ret == Constants.IS_YES) {
            boolean result = cppService.addOrDelIMGroupMember(respClubActivity.getUid(),
                    activityId, respClubActivity.getGroupId(),
                    Lists.newArrayList(order.getOrderUid()), false);
            logger.warn("6 将此人{}剔除活动聊天组{}，返回：{}", order.getOrderUid(), respClubActivity.getGroupId(), result);
            return true;
        }
        return false;
    }

    private void refundBalanceAmount(TbOrder order, String activityName, int clubId) {
        //2. 将抵扣的俱乐部余额退回到俱乐部成员账户
        BigDecimal balance_amount = order.getBalanceAmount();//抵扣的俱乐部余额
        if (balance_amount != null && balance_amount.doubleValue() > 0) {
            ClubMemberAccountStreamInfo info = clubAccountService.addOrDeductionPersonClubAccountBalance(balance_amount, order.getOrderUid(), clubId, true);
            logger.warn("2 退回抵扣余额，" + balance_amount + "，返回：" + JSON.toJSONString(info));
            if (null == info) {
                throw new BizException("退回抵扣金额失败！");
            }
            //记录个人账户流水
            clubAccountService.recordPersonClubAccountDeductibleStream(
                    order.getOrderUid(),
                    order.getActivityId(),
                    activityName + "报名费退款",
                    order.getPayType(), clubId,
                    info,
                    order.getOrderTradeNo(), (byte) 2, (byte) 1);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse activitySettlement(Integer activityId,
                                          Integer clubId, Integer userId, boolean isAuto) {
        if (!clubMemberService.isClubAdminMember(userId, clubId)) {
            return APIResponse.returnFail("请先加入俱乐部并努力获取管理员权限。");
        }
        logger.warn("开始活动结算:" + activityId);
        //结算步骤  1.校验是否可以结算，2.对补请假，AA进行退款操作，并记录退款流水 3.剩余的钱存入俱乐部账户
        RespClubActivity respClubActivity = activityCRUDService.selectClubActivityById(activityId);

        //活动结算条件校验
        APIResponse<List<TbSignUser>> signUserRes = activitySettlementValidated(respClubActivity);
        if (!signUserRes.isRet()) {
            logger.warn("活动结算条件校验不通过");
            return signUserRes;
        }
        logger.warn("开始获取活动报名人员信息..");
        List<TbSignUser> tbSignUsers = signUserRes.getData();

        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria().andActivityIdEqualTo(activityId)
                .andOrderStatusIn(Arrays.asList((byte) 2, (byte) 7))
                .andCancelTypeEqualTo(Constants.BYTE_ZERO);
        //需要退款的订单
        logger.warn("获取活动结算后需要退款的订单..");
        List<TbOrder> needRefundOrders = orderMapper.selectByExample(orderExample);
        Map<Integer, TbOrder> maps = new HashMap<Integer, TbOrder>();
        for (TbOrder o : needRefundOrders) {
            maps.put(o.getId(), o);
        }
        //需要退款的AA报名用户
        List<TbSignUser> needAARefundUsers = Lists.newArrayList();

        //该活动补报名费用总和
        BigDecimal totalMendSignUpFee = new BigDecimal(0);
        BigDecimal totalOnlineMendSignUpFee = new BigDecimal(0);
        logger.warn("结算步骤1：细分各种渠道报名的用户");
        boolean hasRemoved = false;
        for (TbSignUser tbSignUser : tbSignUsers) {

            if (tbSignUser.getManageType().intValue() == 2) {
                //补请假用户退款
                logger.warn("细分步骤1：补请假用户，并退款");
                if (tbSignUser.getIsReplace() == 0) {
                    supplementLeaveRefundOrder(
                            activityId, "现场管理补请假", tbSignUser.getOrderUserId(), (byte) 5);
                    logger.warn("为补请假用户退款成功，开始查找补请假用户的主要信息人的订单..");
                }
                if (tbSignUser.getIsReplace().intValue() == 0
                        && tbSignUser.getOrderId() != null) {
                    TbOrder tbOrder = orderMapper.selectByPrimaryKey(tbSignUser.getOrderId());
                    if (tbOrder != null && CollectionUtils.isNotEmpty(needRefundOrders)) {
                        logger.warn("剔除补请假用户的已退款订单，后续不再进行退款操作。");
                        needRefundOrders.remove(maps.get(tbOrder.getId())); //移除掉补请假的用户
                        hasRemoved = true;
                    }
                }
                continue;
            }
            logger.warn("细分步骤2：补报名用户");
            if (tbSignUser.getManageType().intValue() == 5) {
                //会费支付，记录到线上账户
                if (tbSignUser.getPayChannel() == 0) {
                    logger.warn("计算会费报名的补报名用户的费用总和，后续存入俱乐部线上账户中");
                    totalOnlineMendSignUpFee = totalMendSignUpFee.add(
                            tbSignUser.getMendSignUpAmount() == null ?
                                    new BigDecimal(0) : tbSignUser.getMendSignUpAmount());
                } else if (tbSignUser.getPayChannel() == 1) {
                    //补报名用户,记录到线下账户
                    logger.warn("计算现金报名的补报名用户的费用总和，后续存入俱乐部线下账户中");
                    totalMendSignUpFee = totalMendSignUpFee.add(
                            tbSignUser.getMendSignUpAmount() == null ?
                                    new BigDecimal(0) : tbSignUser.getMendSignUpAmount());
                }
                continue;
            }
            logger.warn("细分步骤3：需要AA退款的用户");
            if (respClubActivity.getFeeType().intValue() == 0) {
                //存放AA付款的用户
                logger.warn("统计需要AA退款的用户，后续进行AA退款操作");
                needAARefundUsers.add(tbSignUser);
            }
        }
        logger.warn("结算步骤2：补报名用户的金额结算");
        if (totalMendSignUpFee.doubleValue() > 0) {
            APIResponse incrementOfflineClubAccountRes =
                    clubAccountService.incrementOfflineClubAccount(respClubActivity.getClubId(),
                            respClubActivity.getActivityId(),
                            totalMendSignUpFee, "活动结算补报名, 增加俱乐部线下账户金额");
            if (!incrementOfflineClubAccountRes.isRet()) {
                logger.warn("现金活动结算补报名, 增加俱乐部线下账户金额失败, 增加金额: "
                        + totalMendSignUpFee.doubleValue() + ", 失败原因: "
                        + incrementOfflineClubAccountRes.getErrmsg());
                throw new BizException("现金活动结算补报名, 增加俱乐部线下账户金额失败");
            }
            logger.warn("现金补报名用户金额结算成功，已添加到俱乐部线下账户中");
        }

        TbClubActivityExample tbClubActivityExample = new TbClubActivityExample();
        tbClubActivityExample.createCriteria().andActivityIdEqualTo(respClubActivity.getActivityId())
                .andClubIdEqualTo(respClubActivity.getClubId());
        //更新活动为已结算
        logger.warn("活动状态设置为已结算");
        TbClubActivity tbClubActivity = null;
        try {
            List<TbClubActivity> tbClubActivities =
                    tbClubActivityMapper.selectByExample(tbClubActivityExample);
            if (CollectionUtils.isEmpty(tbClubActivities)) {
                logger.warn("俱乐部活动结算, 失败原因: " + "修改结算状态失败, 俱乐部ID:" + clubId +
                        ", 活动id: " + activityId);
                throw new BizException("俱乐部活动结算失败");
            }
            tbClubActivity = tbClubActivities.get(0);
            TbClubActivity clubActivity = new TbClubActivity();
            clubActivity.setIsSettle((byte) 1);
            clubActivity.setId(tbClubActivity.getId());
            tbClubActivityMapper.updateByPrimaryKeySelective(clubActivity);
        } catch (Exception e) {
            logger.warn("自动结算更新结算状态异常：" + e.getMessage());
        }
        logger.warn("结算步骤3：线上订单-" + JSONObject.toJSONString(needRefundOrders));
        int signCounts = needRefundOrders.size();
        if (CollectionUtils.isNotEmpty(needRefundOrders)) {
            logger.warn("有订单");
            if (respClubActivity.getFeeType().intValue() == 1) {
                logger.warn("细分线上订单1：固定收费的订单");
                //固定费用结算
                BigDecimal totalAmount = new BigDecimal(0);
                for (TbOrder tbOrder : needRefundOrders) {
                    if (tbOrder.getPayAmount() == null
                            || tbOrder.getPayAmount().doubleValue() <= 0) {
                        //零元订单
                        logger.warn("固定收费的订单1:零元订单,业务系统订单ID-" + tbOrder.getOrderNo());
                        BigDecimal balanceAmount = tbOrder.getBalanceAmount();
                        BigDecimal accumulateFee = new BigDecimal(tbOrder.getAccumulateAmount())
                                .multiply(new BigDecimal(0.1));//暂时写死鸟蛋兑换比例
                        accumulateFee = accumulateFee.setScale(1, RoundingMode.DOWN);
                        totalAmount = totalAmount.add(balanceAmount.add(accumulateFee));
                    } else {
                        logger.warn("固定收费的订单2：非零元订单,业务系统订单ID-" + tbOrder.getOrderNo());
                        totalAmount = totalAmount.add(tbOrder.getOrderAmount());
                    }
                    logger.warn("计算线上固定收费订单总费用：" + totalAmount);
                }
                logger.warn("固定收费的订单3：记录结算流水");
                APIResponse recordRes = recordActivitySettlementStream(needRefundOrders,
                        respClubActivity.getActivityId(), respClubActivity.getClubId());
                if (!recordRes.isRet()) {
                    logger.warn("记录活动结算流水失败, 失败原因: " + recordRes.getErrmsg());
                    throw new BizException("记录活动结算流水失败");
                }

                //把活动报名费用添加到俱乐部账户中
                logger.warn("固定收费的订单4：收入添加到俱乐部账户，零元订单则不用添加");
                if (totalAmount != null && totalAmount.doubleValue() > 0) {
                    logger.warn("固定收费订单5：添加收入到俱乐部账户，收入金额：" + totalAmount);
                    APIResponse apiResponse = clubAccountService.updateClubOnlineAccountBalance(
                            respClubActivity.getClubId(), activityId, NumberGenerator.getNextOrderNo(),
                            String.valueOf(respClubActivity.getActivityId()), totalAmount,
                            "俱乐部活动结算,固定报名费用增加到俱乐部账户中", true, 1);
                    if (!apiResponse.isRet()) {
                        logger.warn("俱乐部活动结算, 固定报名费用增加到俱乐部账户失败, 失败原因: "
                                + apiResponse.getErrmsg() + ", 俱乐部ID:" + clubId +
                                ", 活动id: " + activityId + "增加费用: " + totalAmount);
                        throw new BizException("俱乐部活动结算失败, 失败原因: " + apiResponse.getErrmsg());
                    }
                }
            }
            logger.warn("细分线上订单1：AA收费订单");
            if (respClubActivity.getFeeType().intValue() == 0
                    && CollectionUtils.isNotEmpty(needAARefundUsers)) {
                //AA费用结算
                logger.warn("AA收费订单1：AA退款流程>>");
                APIResponse settlementRefundRes =
                        activityAASettlementRefund(respClubActivity, needAARefundUsers
                                , needRefundOrders);
                if (!settlementRefundRes.isRet()) {
                    logger.warn("AA退款失败，原因：" + settlementRefundRes.getErrmsg());
                    return settlementRefundRes;
                }
            }

        } else if (hasRemoved) {
            APIResponse recordRes = recordActivitySettlementStream(needRefundOrders,
                    respClubActivity.getActivityId(), respClubActivity.getClubId());
            if (!recordRes.isRet()) {
                logger.error("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
                throw new BizException("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
            }
        } else {
            return APIResponse.returnFail("没有需要结算的订单");
        }
        respClubActivity.setIsSettle(1);
        activitySupportService.afterSettlementActivity(isAuto, userId, respClubActivity, needRefundOrders);
        return APIResponse.returnSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void activitySettlementAuto(Integer activityId, Integer clubId, Integer userId) {
        TbSignUserExample userExample = new TbSignUserExample();
        userExample.createCriteria().andStatusEqualTo(1);
        int count = signUserMapper.countByExample(userExample);
        if (count <= 0) {
            logger.warn("这个活动不需要结算啦！");
            return;
        }

        TbClubActivityExample example = new TbClubActivityExample();
        example.createCriteria().andActivityIdEqualTo(activityId);
        List<TbClubActivity> tbClubActivityList = tbClubActivityMapper.selectByExample(example);
        TbClubActivity tbClubActivity = tbClubActivityList.get(0);
        Byte oldStatus = tbClubActivity.getIsSettle();
        if (oldStatus.equals(Constants.BYTE_ONE)) {
            logger.warn("已经结算过了，不再自动结算。");
            return;
        }

        TbSignUserExample signUserExample = new TbSignUserExample();
        signUserExample.createCriteria().andStatusEqualTo(1).andManageTypeEqualTo(0);
        List<TbSignUser> signUserList = signUserMapper.selectByExample(signUserExample);

        TbSignUser user = new TbSignUser();
        user.setManageType(4);
        logger.warn("自动为报名人员签到");
        signUserMapper.updateByExampleSelective(user, signUserExample);

        logger.warn("自动现场管理");
        tbClubActivity.setIsSettle((byte) 2);
        tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);

        String key = activityId + ":" + "settle";
        RedisKey redisKey = new RedisKey(RedisConstants.CLUB_FAMILY_KEY, key);
        APIResponse response = null;
        if (redisTemplate.exists(redisKey)) {
            return;
        } else {
            redisTemplate.set(redisKey, 1);
        }
        try {
            response = activitySettlement(activityId, clubId, userId, true);
            logger.warn("活动自动结算完成，结算结果：" + JSONObject.toJSONString(response));
            if (response.isRet()) {
                logger.warn("设置为已结算，当前状态：" + tbClubActivity.getIsSettle());
                tbClubActivity.setIsSettle((byte) 1);
                tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);
            } else {
                throw new BizException(response.getErrmsg());
            }
        } catch (Exception e) {
            logger.warn("设置为原始状态，当前状态：" + tbClubActivity.getIsSettle());
            tbClubActivity.setIsSettle(oldStatus);
            tbClubActivityMapper.updateByPrimaryKeySelective(tbClubActivity);
            redisTemplate.delteKey(redisKey);
            logger.warn(e.getMessage());
            throw new BizException(e.getMessage());
        }
        redisTemplate.delteKey(redisKey);
        return;
    }

    private void addClubExp(RespClubXpLevelMsg respClubXpLevelMsg) {
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setMsgId(UUID.randomUUID().toString());
        mqRequestMsg.setTopic(MqConstants.CLUB_XP_LEVEL_TOPIC_NAME);
        mqRequestMsg.setFlag(0);
        mqRequestMsg.setTag(MqConstants.CLUB_XP_LEVEL_TAGS_NAME);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(respClubXpLevelMsg));
        clubXpLevelProducer.syncSend(mqRequestMsg);
    }

    private RespClubXpLevelMsg getRespClubXpLevelMsg(Integer userId, RespClubActivity respClubActivity) {
        RespClubXpLevelMsg respClubXpLevelMsg = new RespClubXpLevelMsg();
        respClubXpLevelMsg.setClubId(respClubActivity.getClubId());
        respClubXpLevelMsg.setUid(userId);
        return respClubXpLevelMsg;
    }

    private APIResponse<List<TbSignUser>> activitySettlementValidated(
            RespClubActivity respClubActivity) {

        if (respClubActivity.getStatus().equals((byte) 2)) {
            return APIResponse.returnFail("活动已经取消");
        }

        if (respClubActivity.getIsSettle() == 1) {
            return APIResponse.returnFail("活动已经结算过了");
        }

        if (respClubActivity.getIsSettle() != 2) {
            return APIResponse.returnFail("结算失败, 你还没有对活动进行现场管理");
        }

        if (respClubActivity.getEndTime().getTime() > new Date().getTime()) {
            return APIResponse.returnFail("活动还没有结束");
        }
        List<TbSignUser> users = new ArrayList<TbSignUser>();
        TbSignUserExample tbSignUserExample = new TbSignUserExample();
        TbSignUserExample.Criteria criteria = tbSignUserExample.createCriteria();
        criteria.andActivityIdEqualTo(respClubActivity.getActivityId())
                .andStatusEqualTo(1)
                .andOrderIdIsNull();//计算线下支付的报名人数
        List<TbSignUser> offlineUsers = signUserMapper.selectByExample(tbSignUserExample);
        List<TbSignUser> onlineUsers =
                clubActivityMapper.selectNeedSettleOrderOnline(respClubActivity.getActivityId());
        logger.warn("结果：" + JSONObject.toJSONString(onlineUsers));
        if (CollectionUtils.isNotEmpty(offlineUsers)) {
            users.addAll(offlineUsers);
        } else {
            users.addAll(onlineUsers);
        }
        if (CollectionUtils.isEmpty(users)) {
            return APIResponse.returnFail("没有报名的用户，暂无数据！");
        }
        for (TbSignUser user : users) {
            if (user.getManageType() == 0) {
                logger.warn(JSONObject.toJSONString(users));
                return APIResponse.returnFail("还有成员未被现场管理，无法结算");
            }
        }
        logger.warn(JSONObject.toJSONString(users));
        return APIResponse.returnSuccess(users);
    }

    private APIResponse activityAASettlementRefund(RespClubActivity respClubActivity,
                                                   List<TbSignUser> tbSignUsers,
                                                   List<TbOrder> needRefundOrders) {
        BigDecimal aaTotal = respClubActivity.getAaTotal(); //活动设置总费用
        BigDecimal aaFee = respClubActivity.getAaFee(); //AA费用
        BigDecimal signUpCount = new BigDecimal(tbSignUsers.size()); //人数
        BigDecimal signUpTotalFee = aaFee.multiply(signUpCount); //报名总金额
        //整个活动总退款金额
        BigDecimal totalRefundFee = signUpTotalFee.subtract(aaTotal);
        logger.warn("AA退款流程1：准备AA活动的总退款金额:" + totalRefundFee);
        if (BigDecimal.ZERO.equals(totalRefundFee) || totalRefundFee.doubleValue() <= 0) {
            //报名总金额没有超出活动设置总费用,不需要退款
            //把活动报名费用添加到俱乐部账户中
            logger.warn("AA退款1：AA退款总金额零元");
            if (aaTotal != null && aaTotal.doubleValue() > 0) {
                logger.warn("AA退款总金额零元1：AA活动总金额不为0，不需要进行退款操作，" +
                        "直接结算收入添加到俱乐部线上账户");
                APIResponse uptAccountRes = clubAccountService.updateClubOnlineAccountBalance(
                        respClubActivity.getClubId(), respClubActivity.getActivityId(), NumberGenerator.getNextOrderNo(),
                        String.valueOf(respClubActivity.getActivityId()), signUpTotalFee,
                        "俱乐部AA制活动结算 , 活动费用增加到俱乐部账户中", true, 2);
                if (!uptAccountRes.isRet()) {
                    logger.error("俱乐部AA制活动结算, 活动费用增加到俱乐部账户失败, 失败信息:"
                            + uptAccountRes.getErrmsg());
                    throw new BizException("俱乐部AA制活动结算, 活动费用增加到俱乐部账户失败, 失败信息:"
                            + uptAccountRes.getErrmsg());
                }
            }
            logger.warn("AA退款总金额零元1：记录结算流水，AA退款流程结束");
            APIResponse recordRes = recordActivitySettlementStream(needRefundOrders,
                    respClubActivity.getActivityId(), respClubActivity.getClubId());
            if (!recordRes.isRet()) {
                logger.error("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
                throw new BizException("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
            }
            return APIResponse.returnSuccess();
        }
        logger.warn("AA退款2：AA退款总金额非零元");
        logger.warn("AA退款非零元1:计算退款比例");
        //退款比例
        BigDecimal refundRatioHalf = totalRefundFee.divide(
                signUpTotalFee, 3, BigDecimal.ROUND_HALF_DOWN);
        BigDecimal refundRadio = refundRatioHalf.setScale(2, RoundingMode.DOWN);
        System.out.println(refundRadio.doubleValue());

        //存放所用报名的主要信息人
        logger.warn("AA退款非零元2：计算AA活动的线上报名人信息，后续退款到对应报名人");
        List<TbSignUser> mainSignUser = Lists.newArrayList();
        for (TbSignUser tbSignUser : tbSignUsers) {
            Integer orderUserId = tbSignUser.getOrderUserId();
            if (orderUserId == null) {
                continue;//排除补报名
            }
            if (tbSignUser.getIsReplace().intValue() != 0) {
                continue;
            }
            mainSignUser.add(tbSignUser);
        }

        Collections.sort(mainSignUser, new Comparator<TbSignUser>() {
            @Override
            public int compare(TbSignUser o1, TbSignUser o2) {
                return o2.getCreateTime().compareTo(o1.getCreateTime());
            }
        });

        //这个活动最后一个报名用户
        TbSignUser lastSignUser = mainSignUser.get(0);
//        BigDecimal lastBalanceAmount = null;
        BigDecimal lastPayAmount = null;
//        Long lastAccumulateAmount = null;

        //存在每个主要信息人的退款信息
        List<ResActivitySettlementRefundInfo> mainRefundInfoList = Lists.newArrayList();
        //处理AA退款
        for (TbSignUser tbSignUser : mainSignUser) {
            TbOrder tbOrder = orderMapper.selectByPrimaryKey(tbSignUser.getOrderId());
            if (tbOrder == null) {
                logger.error("活动结算, 用户订单不存在，用户id: " + tbSignUser.getOrderUserId()
                        + " 活动id为: " + tbSignUser.getActivityId());
                throw new BizException("活动结算, 用户订单不存在，用户id: "
                        + tbSignUser.getOrderUserId()
                        + " 活动id为: " + tbSignUser.getActivityId());
            }

            TbSignUserExample tbSignUserExample = new TbSignUserExample();
            TbSignUserExample.Criteria criteria = tbSignUserExample.createCriteria();
            criteria.andActivityIdEqualTo(
                    tbOrder.getActivityId()).andOrderIdEqualTo(tbOrder.getId()).andStatusEqualTo(1);
            Integer replaceNum = signUserMapper.countByExample(tbSignUserExample);
            if (replaceNum == null || replaceNum == 0) {
                logger.error("活动结算, 用户报名信息不存在，用户id: " + tbSignUser.getOrderUserId()
                        + " 活动id为: " + tbSignUser.getActivityId());
                throw new BizException("活动结算, 用户报名信息不存在，用户id: "
                        + tbSignUser.getOrderUserId()
                        + " 活动id为: " + tbSignUser.getActivityId());
            }

            if (tbSignUser.getOrderUserId().intValue()
                    == lastSignUser.getOrderUserId().intValue()) {
//                lastBalanceAmount = tbOrder.getBalanceAmount();
//                lastAccumulateAmount = tbOrder.getAccumulateAmount();
                lastPayAmount = tbOrder.getPayAmount();
            }

            //计算每个主要信息人的退款金额信息
            ResActivitySettlementRefundInfo mainRefundInfo = activitySettlementAARefund(
                    aaTotal,
                    aaFee,
                    signUpCount,
                    refundRadio,
                    tbOrder,
                    replaceNum,
                    respClubActivity.getClubId());
            mainRefundInfoList.add(mainRefundInfo);
        }

        logger.warn("mainRefundInfoList列表信息: " + JSON.toJSONString(mainRefundInfoList));

        List<ResActivitySettlementRefundInfo> eachRefundInfoList = Lists.newArrayList();

        if (mainRefundInfoList.size() >= 1) {
            //最后一个报名主要信息人的第三方退款金额
            BigDecimal lastThirdRefundFee = totalRefundFee;
            //最后一个人的抵扣总额(包含鸟蛋和会费)
            BigDecimal lastUserDeductibleTotalFee = new BigDecimal(0);
            //最后一个人的退款总额
            BigDecimal lastUserRefundTotalFee = new BigDecimal(0);

            ResActivitySettlementRefundInfo lastUserRefundInfo = null;

            for (ResActivitySettlementRefundInfo eachRefundInfo : mainRefundInfoList) {
                if (eachRefundInfo.getUid().intValue()
                        == lastSignUser.getOrderUserId().intValue()) {
                    lastUserDeductibleTotalFee =
                            eachRefundInfo.getAccumulateFee().add(eachRefundInfo.getBalanceFee());
                    lastUserRefundInfo = eachRefundInfo;
                    continue;
                }

                lastThirdRefundFee = lastThirdRefundFee.subtract(
                        eachRefundInfo.getEachRefundTotalFee());

                eachRefundInfoList.add(eachRefundInfo);
            }

            lastUserRefundTotalFee = lastThirdRefundFee;
            lastUserRefundInfo.setEachRefundTotalFee(lastUserRefundTotalFee);

            lastThirdRefundFee = lastThirdRefundFee.subtract(lastUserDeductibleTotalFee);
            if (lastThirdRefundFee.doubleValue() < 0) {
                lastThirdRefundFee = new BigDecimal(0);
            }

            //如果最后一个报名用户的订单是零元订单
//            boolean isZeroOrder =
//                    isAAZeroActivityOrder(aaFee, signUpCount,
//                            lastBalanceAmount, new BigDecimal(lastAccumulateAmount));
            if (lastPayAmount == null || lastPayAmount.doubleValue() <= 0) {
                //零元订单
                lastUserRefundInfo.setBalanceFee(lastUserRefundTotalFee.
                        subtract(lastUserRefundInfo.getAccumulateFee()));
                lastUserRefundInfo.setThirdRefundFee(new BigDecimal(0));//第三方不退
            } else {
                lastUserRefundInfo.setThirdRefundFee(lastThirdRefundFee);
            }

            eachRefundInfoList.add(lastUserRefundInfo);
            logger.warn("最后一个人的退款金额: " + lastThirdRefundFee);
        }

        APIResponse recordRes = recordActivitySettlementStream(needRefundOrders,
                respClubActivity.getActivityId(), respClubActivity.getClubId());
        if (!recordRes.isRet()) {
            logger.error("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
            throw new BizException("记录活动结算流水失败, 失败信息: " + recordRes.getErrmsg());
        }

        if (aaTotal != null && aaTotal.doubleValue() > 0) {
            //把活动报名费用添加到俱乐部账户中
            logger.warn("aatotal > 0,添加AA费用到俱乐部账户:" + aaTotal);
            APIResponse uptAccountRes = clubAccountService.updateClubOnlineAccountBalance(
                    respClubActivity.getClubId(), respClubActivity.getActivityId(), NumberGenerator.getNextOrderNo(),
                    String.valueOf(respClubActivity.getActivityId()), aaTotal,
                    "俱乐部AA制活动结算 , 活动费用增加到俱乐部账户中", true, 2);
            if (!uptAccountRes.isRet()) {
                logger.error("俱乐部AA制活动结算, 活动费用增加到俱乐部账户失败, 失败信息:"
                        + uptAccountRes.getErrmsg());
                throw new BizException("俱乐部AA制活动结算, 活动费用增加到俱乐部账户失败, 失败信息:"
                        + uptAccountRes.getErrmsg());
            }
        }

        logger.warn("处理后的mainRefundInfoList列表信息: " + JSON.toJSONString(eachRefundInfoList));

        if (eachRefundInfoList.size() == 0) {
            return APIResponse.returnSuccess();
        }

        for (ResActivitySettlementRefundInfo eachRefundInfo : eachRefundInfoList) {

            logger.warn("活动AA退款信息, 活动ID: " + eachRefundInfo.getActivityId()
                    + "用户ID: " + eachRefundInfo.getUid()
                    + "请求退款数据: " + JSON.toJSONString(eachRefundInfo));

            String refundOrderNo = CommonUtils.generateOrderNo(eachRefundInfo.getUid());
            if (eachRefundInfo.getBalanceFee().doubleValue() > 0) {
                //退回抵扣会费
                ClubMemberAccountStreamInfo accountStreamInfo =
                        clubAccountService.addOrDeductionPersonClubAccountBalance(
                                eachRefundInfo.getBalanceFee(),
                                eachRefundInfo.getUid(),
                                respClubActivity.getClubId(), true);
                if (accountStreamInfo == null) {
                    logger.error("AA活动退回抵扣会费失败, 订单号: " + eachRefundInfo.getOrderNo());
                    throw new BizException("AA活动退回抵扣会费失败, 订单号: "
                            + eachRefundInfo.getOrderNo());
                }

                //记录AA退款个人账户流水
                clubAccountService.recordPersonClubAccountDeductibleStream(
                        accountStreamInfo.getUserId(),
                        respClubActivity.getActivityId(),
                        respClubActivity.getName() + "AA付款结算退款",
                        eachRefundInfo.getPayType().byteValue(),
                        respClubActivity.getClubId(), accountStreamInfo,
                        eachRefundInfo.getOrderNo(), (byte) 2, (byte) 1);
            }

            //退款申请记录
            boolean isSuccess = insertOrderRefund(
                    eachRefundInfo.getThirdRefundFee(),
                    eachRefundInfo.getOrderId(),
                    eachRefundInfo.getPayType(),
                    eachRefundInfo.getUid(), "活动结算AA退款",
                    (byte) 1, refundOrderNo);
            if (!isSuccess) {
                logger.error("插入退款申请记录失败, 订单id: " + eachRefundInfo.getOrderId());
                throw new BizException("插入退款申请记录失败, 订单id: " + eachRefundInfo.getOrderId());
            }

            if (eachRefundInfo.getAccumulateCount().doubleValue() <= 0
                    && eachRefundInfo.getThirdRefundFee().doubleValue() <= 0) {
                // 不走支付系统退款
                logger.warn("不走支付系统退款用户ID: " + eachRefundInfo.getUid()
                        + "数据信息: " + JSON.toJSONString(eachRefundInfo));
                recordAASettlementRefundDetail(eachRefundInfo);
                continue;
            }

            logger.warn("发起AA结算退款用户ID: " + eachRefundInfo.getUid()
                    + "请求退款数据: " + JSON.toJSONString(eachRefundInfo));

            //调用支付系统AA退款接口
            APIResponse<RefundStatusEnum> apiResponse =
                    invokeActivityAARefund(eachRefundInfo, refundOrderNo, respClubActivity.getName());
            if (!apiResponse.isRet()) { //申请退款失败
                logger.error("调用支付系统AA退款接口失败, 失败信息: " + apiResponse.getErrmsg());
                throw new BizException("调用支付系统AA退款接口失败, 失败信息: " + apiResponse.getErrmsg());
            }

            recordAASettlementRefundDetail(eachRefundInfo);
        }

        return APIResponse.returnSuccess();
    }

    private APIResponse recordAASettlementRefundDetail(
            ResActivitySettlementRefundInfo refundInfo) {
        TbAASettlementRefundDetail refundDetail = new TbAASettlementRefundDetail();
        refundDetail.setOrderNo(refundInfo.getOrderNo());
        refundDetail.setActivityId(refundInfo.getActivityId());
        refundDetail.setOrderUid(refundInfo.getUid());
        refundDetail.setPayId(refundInfo.getPayType());
        if (refundInfo.getAccumulateCount().doubleValue() <= 0
                && refundInfo.getThirdRefundFee().doubleValue() <= 0) {
            logger.warn("不走支付系统付款，直接录入退款完成");
            refundDetail.setRefundStatus((byte) 2);
        } else {
            refundDetail.setRefundStatus(Constants.BYTE_ONE);
        }

        refundDetail.setRefundAccumulateAmount(refundInfo.getAccumulateCount());
        refundDetail.setRefundBalanceAmount(refundInfo.getBalanceFee());
        refundDetail.setRefundThirdPartyAmount(refundInfo.getThirdRefundFee());
        refundDetail.setCreateTime(new Date());
        boolean isSuccess = clubAccountService.recordAASettlementRefundDetail(refundDetail);
        if (!isSuccess) {
            return APIResponse.returnFail("记录AA活动结算明细失败");
        }
        return APIResponse.returnSuccess();
    }

    public APIResponse<RefundStatusEnum> invokeActivityAARefund(
            ResActivitySettlementRefundInfo refundInfo,
            String businessRefundNo, String activityName) {

        //支付信息 包含积分、第三方支付
        List<ReqRefundPayInfo> payInfoList = new ArrayList<>();

        if (refundInfo.getAccumulateCount() != null && refundInfo.getAccumulateCount() > 0) {
            ReqRefundPayInfo reqRefundAccumulateInfo = new ReqRefundPayInfo();
            reqRefundAccumulateInfo.setPayId(PayWayEnum.PAY_WAY_FOR_AGES.getPayId());
            reqRefundAccumulateInfo.setRefundAmount(new BigDecimal(refundInfo.getAccumulateCount()));
            payInfoList.add(reqRefundAccumulateInfo);
        }

        if (refundInfo.getThirdRefundFee() != null
                && refundInfo.getThirdRefundFee().doubleValue() > 0) {
            ReqRefundPayInfo reqRefundPayInfo = new ReqRefundPayInfo();
            reqRefundPayInfo.setPayId(refundInfo.getPayType().intValue());
            reqRefundPayInfo.setRefundAmount(refundInfo.getThirdRefundFee());
            payInfoList.add(reqRefundPayInfo);
        }

        //商品信息
        List<ReqRefundProduct> reqRefundProductList = new ArrayList<>();
        ReqRefundProduct reqRefundProduct = new ReqRefundProduct();
        reqRefundProduct.setProductId(refundInfo.getActivityId() + "");
        reqRefundProductList.add(reqRefundProduct);

        ReqOrderRefund reqOrderRefund = new ReqOrderRefund();
        reqOrderRefund.setOrderNo(refundInfo.getOrderTradeNo());
        reqOrderRefund.setNeedAudit(false);
        reqOrderRefund.setOutTradeNo(refundInfo.getOrderNo());
        reqOrderRefund.setOutTradeRefundNo(businessRefundNo);
        reqOrderRefund.setReason("俱乐部活动AA退款");
        reqOrderRefund.setEggInfo(activityName + "AA付款结算退款");
        reqOrderRefund.setUid(refundInfo.getUid());
        reqOrderRefund.setSourceBusinessId(Constants.CLUB_ACTIVITY_AA_REFUND_ORDER_BUSINESS_CODE);
        reqOrderRefund.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
        reqOrderRefund.setReqRefundPayInfos(payInfoList);
        reqOrderRefund.setRefundProductList(reqRefundProductList);
        APIRequest apiRequest = new APIRequest();
        apiRequest.setData(reqOrderRefund);

        APIResponse<RefundStatusEnum> enumAPIResponse = orderPayService.refundApply(apiRequest);

        return enumAPIResponse;
    }


    public ResActivitySettlementRefundInfo activitySettlementAARefund(
            BigDecimal aaTotal,
            BigDecimal aaFee,
            BigDecimal signUpCount,
            BigDecimal refundRadio,
            TbOrder tbOrder,
            int replaceNum, //代报名人数
            Integer clubId) {

        BigDecimal accumulateAmount = new BigDecimal(tbOrder.getAccumulateAmount());
        BigDecimal balanceAmount = tbOrder.getBalanceAmount();

        Long accumulateCount = 0l; //要退款鸟蛋个数
        BigDecimal accumulateFee = new BigDecimal(0); //要退还鸟蛋对应的金额

        if (accumulateAmount.doubleValue() > 0) {
            BigDecimal accumulateRefundFee = accumulateAmount.multiply(refundRadio);
            accumulateCount = accumulateRefundFee.longValue();
            DecimalFormat decimalFormat = new DecimalFormat("0");
            accumulateCount = Long.parseLong(decimalFormat.format(accumulateCount));
            accumulateFee = accumulateRefundFee.multiply(new BigDecimal(0.1));
            accumulateFee = accumulateFee.setScale(1, RoundingMode.DOWN);
        }

        BigDecimal balanceFee = new BigDecimal(0); //俱乐部会费退还金额
        if (balanceAmount.doubleValue() > 0) {
            balanceFee = balanceAmount.multiply(refundRadio);
            balanceFee = balanceFee.setScale(2, RoundingMode.DOWN);
        }

        //活动实际单人价格
        BigDecimal eachSignUpFee = aaTotal.divide(
                signUpCount, 3, BigDecimal.ROUND_HALF_DOWN);
        eachSignUpFee = eachSignUpFee.setScale(2, RoundingMode.DOWN);

        //该人应交报名费
        BigDecimal needSignUpFee = eachSignUpFee.multiply(new BigDecimal(replaceNum));

        //需要给这个人退还的第三方金额
        BigDecimal thirdRefundFee = null;
//        boolean isZeroOrder =
//                isAAZeroActivityOrder(aaFee, signUpCount, balanceAmount, accumulateAmount);
        if (tbOrder.getPayAmount() == null || tbOrder.getPayAmount().doubleValue() <= 0) {
            //零元订单
            if (balanceAmount.doubleValue() > 0) {
                balanceFee = tbOrder.getOrderAmount().subtract(needSignUpFee).
                        subtract(accumulateFee);
                balanceFee = balanceFee.setScale(2, RoundingMode.DOWN);
            }

            thirdRefundFee = new BigDecimal(0);

        } else {
            if (balanceAmount.doubleValue() > 0) {
                balanceFee = balanceAmount.multiply(refundRadio);
                balanceFee = balanceFee.setScale(2, RoundingMode.DOWN);
            }
            thirdRefundFee = tbOrder.getOrderAmount().subtract(needSignUpFee).
                    subtract(accumulateFee).subtract(balanceFee);
            thirdRefundFee = thirdRefundFee.setScale(2, RoundingMode.DOWN);
        }


        //需要给这个人总退款金额
        BigDecimal eachRefundTotalFee = accumulateFee.add(balanceFee).add(thirdRefundFee);

        ResActivitySettlementRefundInfo mainRefundInfo = new ResActivitySettlementRefundInfo();
        mainRefundInfo.setUid(tbOrder.getOrderUid());
        mainRefundInfo.setOrderId(tbOrder.getId());
        mainRefundInfo.setClubId(clubId);
        mainRefundInfo.setActivityId(tbOrder.getActivityId());
        mainRefundInfo.setOrderNo(tbOrder.getOrderNo());
        mainRefundInfo.setOrderTradeNo(tbOrder.getOrderTradeNo());
        mainRefundInfo.setPayType(tbOrder.getPayType());
        mainRefundInfo.setEachRefundTotalFee(eachRefundTotalFee);
        mainRefundInfo.setThirdRefundFee(thirdRefundFee);
        mainRefundInfo.setAccumulateCount(accumulateCount);
        mainRefundInfo.setAccumulateFee(accumulateFee);
        mainRefundInfo.setBalanceFee(balanceFee);

        return mainRefundInfo;
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse handleActivityPayResponse(String msgId, OrderNotifyMsg orderNotifyMsg) {
        logger.warn("支付系统回调返回信息，orderNotifyMsg:  " + JSON.toJSONString(orderNotifyMsg));
        logger.warn("接收支付系统回调消息 , 业务系统订单号: " + orderNotifyMsg.getOutTradeNo());

//        OrderCallBackMsg orderCallBackMsg = new OrderCallBackMsg();
//        orderCallBackMsg.setOrderNo(orderNotifyMsg.getOrderNo());
//        orderCallBackMsg.setType(OrderCallBackMsg.PAY);

        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andOrderNoEqualTo(orderNotifyMsg.getOutTradeNo())
                .andOrderTradeNoEqualTo(orderNotifyMsg.getOrderNo());
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);
        if (CollectionUtils.isEmpty(tbOrders)) {
            //理论上不存在订单不存在
            logger.error("接收支付系统回调消息,查询订单不存在! 业务系统订单号: "
                    + orderNotifyMsg.getOutTradeNo());
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return APIResponse.returnFail("订单不存在");
        }

        TbOrder tbOrder = tbOrders.get(0);

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId(), null);
        if (!activityAPIResponse.isRet()) {
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return APIResponse.returnFail("支付回调远程调用dubbo查询活动信息失败, 活动id: "
                    + tbOrder.getActivityId() + "用户id: " + tbOrder.getOrderUid());
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        Integer handleStatus = 3;  //1：处理成功 2处理中 3：处理失败

        if (orderNotifyMsg.getResultCode().equals(
                OrderNotifyMsg.RESULT_CODE_USER_PAY_SUCCESS)) {
            tbOrder.setOrderStatus((byte) 2); //支付成功
            handleStatus = 1;
            tbOrder.setPayTime(new Date(orderNotifyMsg.getPayTime())); //支付时间
//            orderCallBackMsg.setState(OrderCallBackMsg.SUCCESS);
            logger.warn("支付成功，用户id：" + tbOrder.getOrderUid()
                    + "业务系统订单号：" + tbOrder.getOrderNo());

            //推送给管理员报名通知
            List<Integer> clubAdminUids = cumstomClubMemberMapper.selectClubAdminsByClubId(respClubActivity.getClubId());
            if (CollectionUtils.isNotEmpty(clubAdminUids)) {
                pushNotify(respClubActivity, tbOrder.getOrderUid(), 1, clubAdminUids);
            }

            //将主要信息人加入活动群组
            Integer activityId = tbOrder.getActivityId();
            if (null != activityId && activityId > 0) {
                Integer groupUid = clubActivityMapper.selectUidByActivityId(activityId);
                if (null != groupUid) {
                    cppService.addOrDelIMGroupMember(groupUid, activityId, respClubActivity.getGroupId(),
                            Lists.newArrayList(tbOrder.getOrderUid()), true);
                }
            }


        } else if (orderNotifyMsg.getResultCode().equals(
                OrderNotifyMsg.RESULT_CODE_USER_PAY_FAIL)) {
            tbOrder.setOrderStatus((byte) 3);//支付失败
            handleStatus = 3;
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            logger.error("支付失败，用户id：" + tbOrder.getOrderUid() + "业务系统订单号："
                    + tbOrder.getOrderNo() + "订单系统订单号：" + orderNotifyMsg.getOrderNo());
        }

        TbClubOnlineMemberAccountStream tbClubOnlineMemberAccountStream
                = clubAccountService.getPersonClubAccountStream(
                tbOrder.getOrderUid(), respClubActivity.getClubId(),
                respClubActivity.getActivityId(), 1);
        logger.warn("查询个人流水为: " + tbClubOnlineMemberAccountStream);
        if (tbClubOnlineMemberAccountStream != null) {
            tbClubOnlineMemberAccountStream.setStatus(handleStatus.byteValue());
            clubAccountService.updatePersonClubAccountStream(tbClubOnlineMemberAccountStream);
        }

        int count = orderMapper.updateByPrimaryKeySelective(tbOrder);
//        if (count <= 0) {
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//        }
//        feedbackOrderSystemOrderStatus(orderCallBackMsg);

        logger.warn("修改订单状态成功 !");
        String address = null;
        if (null == (address = respClubActivity.getPlaceAddress())) {
            if (null != respClubActivity.getPlaceDubboProvider()) {
                PlaceDubboProvider pd = respClubActivity.getPlaceDubboProvider();
                address = pd.getName();
            }
        }
        TbSignUserExample userExample = new TbSignUserExample();
        userExample.createCriteria().andOrderIdEqualTo(tbOrder.getId());
        List<TbSignUser> signUsers = signUserMapper.selectByExample(userExample);
        if (null != signUsers && signUsers.size() == 1) {
            TbSignUser signUser = signUsers.get(0);
            try {
                clubSmsService.sendSms(signUser.getMobile(),
                        ClubSmsService.CLUB_MESSAGE_TEMPLATE_PLACE_ACTIVITY_NOTICE,
                        Arrays.asList(respClubActivity.getClubName(),
                                respClubActivity.getName(),
                                DateUtils.convertDateToString(respClubActivity.getStartTime()), address));
                cppService.pushActivitySignUp(respClubActivity, tbOrder.getOrderUid(), orderNotifyMsg.getLarkAppId());
            } catch (Exception e) {
                logger.warn("报名成功，发送短信失败：参数：" + JSONObject.toJSONString(signUser)
                        + JSONObject.toJSONString(respClubActivity) + e.getMessage());
            }

        }
        return APIResponse.returnSuccess();
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse handleActivityOrderCloseCallBack(OrderNotifyMsg orderNotifyMsg) {
        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andOrderStatusEqualTo(Constants.BYTE_ONE)
                .andOrderNoEqualTo(orderNotifyMsg.getOutTradeNo());
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);
        if (CollectionUtils.isEmpty(tbOrders)) {
            throw new BizException("执行订单关闭失败, 错误信息: 查询订单不存在, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
        }

        TbOrder tbOrder = tbOrders.get(0);
        OrderCallBackMsg orderCallBackMsg = new OrderCallBackMsg();
        orderCallBackMsg.setOrderNo(tbOrder.getOrderTradeNo());
        orderCallBackMsg.setType(OrderCallBackMsg.CLOSE);

        TbSignUserExample signUserExample = new TbSignUserExample();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(tbOrder.getActivityId()) //活动id
                .andStatusEqualTo((int) Constants.BYTE_ONE)          //有效的
                .andOrderIdEqualTo(tbOrder.getId());
        List<TbSignUser> signUsers = signUserMapper.selectByExample(signUserExample);
        if (CollectionUtils.isEmpty(signUsers)) {
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("执行订单关闭失败, 错误信息: 订单关联的活动报名人不存在, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
            throw new BizException("执行订单关闭失败, 错误信息: 订单关联的活动报名人不存在, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
        }

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId(), null);
        if (!activityAPIResponse.isRet()) {
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("执行订单关闭失败, 错误信息: 调用dubbo查询活动信息失败, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
            throw new BizException("执行订单关闭失败, 错误信息: 调用dubbo查询活动信息失败, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
        }

        tbOrder.setOrderStatus(Constants.BYTE_ZERO);//设置成超时未支付
        int count = orderMapper.updateByPrimaryKeySelective(tbOrder);
        if (count <= 0) {
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("执行订单关闭, 更新订单状态失败, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
            throw new BizException("执行订单关闭, 更新订单状态失败, 业务订单号: "
                    + orderNotifyMsg.getOutTradeNo());
        }

        //计算要取消的男女报名人数
        int manCount = 0, femaleCount = 0;
        for (TbSignUser signUser : signUsers) {
            if (signUser.getGender() == Constants.BYTE_ONE) {
                manCount++;
            }
            if (signUser.getGender() == Constants.BYTE_TWO) {
                femaleCount++;
            }
        }

        //从活动报名人数库存中减去取消的男女人数
        Map<String, Object> paraMap = Maps.newHashMap();
        paraMap.put("activityId", tbOrder.getActivityId());

        RespClubActivity respClubActivity = activityAPIResponse.getData();
        try {
            APIResponse recoveryRes = recoverySignUpNum(
                    respClubActivity.getLimitNum(), tbOrder.getActivityId(), signUsers.size(), femaleCount, 0);

            logger.warn("3 恢复报名人数库存，男：" + signUsers.size() + ", 女：" + femaleCount + ", 返回：" + JSON.toJSONString(recoveryRes));
            if (!recoveryRes.isRet()) {
                throw new BizException("恢复报名人库存异常：" + JSON.toJSONString(recoveryRes));
            }
            logger.warn("更新报名人数完成, minusCount" + signUsers.size());
        } catch (RpcException rpe) {
            throw new BizException("调用活动模块失败" + JSON.toJSONString(paraMap));
        }
        //4. 更新报名人报名记录表
        signUserExample.clear();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(tbOrder.getActivityId())
                .andOrderIdEqualTo(tbOrder.getId());
        TbSignUser updateSignUser = new TbSignUser();
        updateSignUser.setStatus(-1);//这里设置为下单超时未支付状态,现场管理成员列表中会去过滤掉超时未支付的.
        int uret = signUserMapper.updateByExampleSelective(updateSignUser, signUserExample);
        logger.warn("4 更新报名人报名记录表，更新为{}，返回：{}", JSON.toJSON(updateSignUser), uret);
        orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
        feedbackOrderSystemOrderStatus(orderCallBackMsg);


        //如果有俱乐部余额抵扣 , 则退回
        if (tbOrder.getBalanceAmount() != null
                && tbOrder.getBalanceAmount().doubleValue() > 0) {
            ClubMemberAccountStreamInfo clubMemberAccountStreamInfo =
                    clubAccountService.addOrDeductionPersonClubAccountBalance(tbOrder.getBalanceAmount(),
                            tbOrder.getOrderUid(), respClubActivity.getClubId(), true);

            if (clubMemberAccountStreamInfo == null) {
                orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
                feedbackOrderSystemOrderStatus(orderCallBackMsg);
                logger.error("执行订单关闭失败, 错误信息: 增加账户余额失败 业务订单号: "
                        + orderNotifyMsg.getOutTradeNo());
                throw new BizException("执行订单关闭失败, 错误信息: 增加账户余额失败 业务订单号: "
                        + orderNotifyMsg.getOutTradeNo());
            }
            //把下单时插入状态为(status = 2)处理中的流水记录删除
            TbClubOnlineMemberAccountStream tbClubOnlineMemberAccountStream
                    = clubAccountService.getPersonClubAccountStream(
                    tbOrder.getOrderUid(), respClubActivity.getClubId(),
                    respClubActivity.getActivityId(), 1);
            if (tbClubOnlineMemberAccountStream != null) {
                clubAccountService.deletePersonClubAccountStream(
                        tbClubOnlineMemberAccountStream.getId());
            }
            //记录个人账户流水, 插入一条退款流水记录
            //status 0:待处理 1：处理成功 2处理中 3：处理失败
            clubAccountService.recordPersonClubAccountDeductibleStream(
                    tbOrder.getOrderUid(),
                    tbOrder.getActivityId(),
                    respClubActivity.getName() + "报名费退款",
                    tbOrder.getPayType(), respClubActivity.getClubId(),
                    clubMemberAccountStreamInfo,
                    tbOrder.getOrderTradeNo(), (byte) 2, (byte) 2);
        }

        orderCallBackMsg.setState(OrderCallBackMsg.SUCCESS);
        feedbackOrderSystemOrderStatus(orderCallBackMsg);

        return APIResponse.returnSuccess();
    }

    private void feedbackOrderSystemOrderStatus(OrderCallBackMsg orderCallBackMsg) {
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setTopic(OrderPayService.TOPIC_ORDER_CALLBACK_NOTIFY);
        mqRequestMsg.setTag(Constants.ORDER_SYSTEM_CODE);
        mqRequestMsg.setMsgId(orderCallBackMsg.getOrderNo()); //订单号.
        mqRequestMsg.setFlag(0);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(orderCallBackMsg));
        activityOrderPayRelatedClientImpl.asyncSend(mqRequestMsg);
    }

    @Override
    public APIResponse recordActivitySettlementStream(List<TbOrder> orderList,
                                                      Integer activityId, Integer clubId) {

        TbClubActivitySettlementDetail settlementDetail = new TbClubActivitySettlementDetail();
        TbClubActivitySettlement tbClubActivitySettlement = new TbClubActivitySettlement();

        BigDecimal dealMoney = new BigDecimal(0);
        BigDecimal accumulateMoney = new BigDecimal(0);
        BigDecimal payMoney = new BigDecimal(0);
        BigDecimal couponAmount = new BigDecimal(0);

        for (TbOrder tbOrder : orderList) {

            settlementDetail.setUid(tbOrder.getOrderUid());
            settlementDetail.setClubId(clubId);
            settlementDetail.setActivityId(activityId);
            settlementDetail.setType(Constants.IS_YES);
            settlementDetail.setCreateTime(new Date());
            logger.warn("订单-" + JSONObject.toJSONString(tbOrder));
            settlementDetail.setDealMoney(tbOrder.getOrderAmount());
            settlementDetail.setPayMoney(tbOrder.getPayAmount());
            settlementDetail.setAccumulateMoney(tbOrder.getExchangeRmb());
            dealMoney = dealMoney.add(tbOrder.getOrderAmount());
            accumulateMoney = accumulateMoney.add(tbOrder.getExchangeRmb());
            /*if(null != tbOrder.getCouponAmount())
            {
                settlementDetail.setCouponCode(tbOrder.getCouponCode());
                settlementDetail.setCouponAmount(tbOrder.getCouponAmount());
                couponAmount = couponAmount.add(tbOrder.getCouponAmount());
            }*/
            payMoney = payMoney.add(tbOrder.getPayAmount());

            settlementDetailMapper.insertSelective(settlementDetail);
        }

        tbClubActivitySettlement.setClubId(clubId);
        tbClubActivitySettlement.setActivityId(activityId);
        tbClubActivitySettlement.setDealMoney(dealMoney);//总金额
        tbClubActivitySettlement.setAccumulateMoney(accumulateMoney);
        //tbClubActivitySettlement.setCouponAmount(couponAmount);
        tbClubActivitySettlement.setPayMoney(payMoney);
        tbClubActivitySettlement.setCreateTime(new Date());
        tbClubActivitySettlement.setType(Constants.IS_YES);
        TbClubActivitySettlementExample settlementExample
                = new TbClubActivitySettlementExample();
        settlementExample.createCriteria().andActivityIdEqualTo(activityId);
        int count = settlementMapper.countByExample(settlementExample);
        if (count > 0) {
            throw new BizException("已经在结算中了");
        }
        settlementMapper.insertSelective(tbClubActivitySettlement);

        return APIResponse.returnSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse handleActivitySettlementAARefundCallback(
            RefundNotifyMsg refundNotifyMsg, TbOrderRefund tbOrderRefund) {

        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andOrderNoEqualTo(refundNotifyMsg.getOutTradeNo())
                .andOrderTradeNoEqualTo(refundNotifyMsg.getOrderNo());
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);

//        OrderCallBackMsg orderCallBackMsg = new OrderCallBackMsg();

        if (CollectionUtils.isEmpty(tbOrders)) {
            //理论上不存在订单不存在
            logger.error("该订单AA结算消息回调, 查询订单不存在, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo()
                    + ", 订单系统订单号: " + refundNotifyMsg.getOrderNo());
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return APIResponse.returnFail("订单不存在");
        }

        TbOrder tbOrder = tbOrders.get(0);
//        orderCallBackMsg.setType(OrderCallBackMsg.REFUND);
//        orderCallBackMsg.setOrderNo(tbOrder.getOrderTradeNo());

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId());
        if (!activityAPIResponse.isRet()) {
            logger.error("该订单AA结算消息回调, 调用dubbo查询活动失败! 失败信息: " +
                    activityAPIResponse.getErrmsg() + ", 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo()
                    + ", 订单系统订单号: " + refundNotifyMsg.getOrderNo());
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return activityAPIResponse;
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();

        TbAASettlementRefundDetail settlementRefundDetail =
                clubAccountService.getTbAASettlementRefundDetail(
                        tbOrder.getOrderNo(), tbOrder.getActivityId());
        if (settlementRefundDetail == null) {
            logger.error("该订单AA结算明细不存在, 订单号: " + tbOrder.getOrderNo());
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            return APIResponse.returnFail("该订单AA结算明细不存在, 订单号: " + tbOrder.getOrderNo());
        }


        if (refundNotifyMsg.getRefundState().equals(RefundStatusEnum.SUCCESS.getId())) {
//            //退回抵扣会费
//            ClubMemberAccountStreamInfo accountStreamInfo =
//                    clubAccountService.addOrDeductionPersonClubAccountBalance(
//                            settlementRefundDetail.getRefundBalanceAmount(),
//                            settlementRefundDetail.getOrderUid(),
//                            respClubActivity.getClubId(), true);
//            if (accountStreamInfo == null) {
//                logger.error("AA活动退回抵扣会费失败, 订单号: " + tbOrder.getOrderNo());
////                orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
////                feedbackOrderSystemOrderStatus(orderCallBackMsg);
//                throw new BizException("AA活动退回抵扣会费失败, 订单号: " + tbOrder.getOrderNo());
//            }
//
//            //记录AA退款个人账户流水
//            clubAccountService.recordPersonClubAccountDeductibleStream(
//                    accountStreamInfo.getUserId(),
//                    respClubActivity.getActivityId(),
//                    respClubActivity.getName() + "AA付款结算退款",
//                    tbOrder.getPayType().byteValue(),
//                    respClubActivity.getClubId(), accountStreamInfo,
//                    refundNotifyMsg.getOrderNo(), (byte) 2, (byte) 1);

            tbOrder.setOrderStatus((byte) 6); //AA退款成功
            settlementRefundDetail.setRefundStatus((byte) 2);
            tbOrderRefund.setState((byte) 1);
            tbOrderRefund.setAudit((byte) 1);
//            orderCallBackMsg.setState(OrderCallBackMsg.SUCCESS);

            /*cppService.pushAARefundSuccessForActivityMsg(
                    settlementRefundDetail,
                    respClubActivity.getClubId(),
                    respClubActivity.getName());*/

        } else if (refundNotifyMsg.getRefundState().equals(
                RefundStatusEnum.FAIL.getId())) {
            //AA退款失败
            settlementRefundDetail.setRefundStatus((byte) 3);
            tbOrderRefund.setState((byte) 2);
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("支付系统消息回调, 俱乐部活动结算AA退款失败, 业务订单号: " + tbOrder.getOrderNo());
            APIResponse.returnFail("俱乐部活动结算AA退款失败");
        }

        boolean isSuccess = clubAccountService
                .updateTbAASettlementRefundDetailStatus(settlementRefundDetail);
        if (!isSuccess) {
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("更新AA活动结算明细状态失败, 订单号: " + tbOrder.getOrderNo());
            throw new BizException("更新AA活动结算明细状态失败, 订单号: " + tbOrder.getOrderNo());

        }

        int count = orderMapper.updateByPrimaryKeySelective(tbOrder);
//        if (count <= 0) {
//            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
//            feedbackOrderSystemOrderStatus(orderCallBackMsg);
//            logger.error("结算退款MQ回调, 更新订单状态失败, 订单号: " + tbOrder.getOrderNo());
//            throw new BizException("结算退款MQ回调, 更新订单状态失败, 订单号: " + tbOrder.getOrderNo());
//        }

//        feedbackOrderSystemOrderStatus(orderCallBackMsg);
        return APIResponse.returnSuccess();
    }

    //恢复活动人数库存
    public APIResponse recoverySignUpNum(Integer limitNum,
                                         Integer activityId, Integer manCount,
                                         Integer femaleCount, int type) {
        femaleCount = 0;//不分男女，外层只传总数到男性
        Map<String, Object> paraMap = Maps.newHashMap();
        paraMap.put("activityId", activityId);
        paraMap.put("type", type);

        int affectTotalCount = 0;
        int affectManCount = 0;
        int affectWomenCount = 0;

        paraMap.put("totalCount", manCount + femaleCount);

        logger.warn("恢复活动报名：" + JSON.toJSONString(paraMap));
        affectTotalCount = clubActivityMapper.recoveryLockSignTotalNum(paraMap);
        if (affectTotalCount <= 0) {
            return APIResponse.returnFail("恢复活动报名总人数库存失败");
        }
        //扣除响应人数
        clubActivityMapper.deductionSignTotalNum(paraMap);

//        if (respClubActivity.getMaleLimitNum() > 0) {
//            paraMap.put("manCount", manCount);
//            affectManCount = clubActivityMapper.recoverySignManNum(paraMap);
//            if (affectManCount <= 0) {
//                return APIResponse.returnFail("恢复活动报名男生人数库存失败");
//            }
//        }
//
//        if (respClubActivity.getFemaleLimitNum() > 0) {
//            paraMap.put("womenCount", femaleCount);
//            affectWomenCount = clubActivityMapper.recoverySignWomenNum(paraMap);
//            if (affectWomenCount <= 0) {
//                return APIResponse.returnFail("恢复活动报名女生人数库存失败");
//            }
//        }

        return APIResponse.returnSuccess();
    }

    /**
     * 批量增加活动海报列表
     */
    @Override
    public APIResponse batchAddActivityPoster(
            List<String> urls, int uid, int categoryId, int clubId) {
        //判断用户是否是这个俱乐部的
        if (!clubMemberService.isClubMember(uid, clubId)) {
            return APIResponse.returnFail("你还不是这个俱乐部的小伙伴呀！");
        }
        List<TbActivityPoster> posters = new ArrayList<TbActivityPoster>();
        for (String url : urls) {
            TbActivityPoster poster = new TbActivityPoster();
            poster.setUrl(url);
            poster.setCategoryId(categoryId);
            poster.setClubId(clubId);
            posters.add(poster);
        }
        logger.warn("调测日志,批量添加活动海报：" + JSONObject.toJSONString(posters));
        int count = clubActivityMapper.batchInsertPoster(posters);
        if (count <= 0) {
            return APIResponse.returnFail("啊呀，添加失败啦！");
        }
        return APIResponse.returnSuccess();
    }

    @Override
    public APIResponse batchDeleteActivityPoster(
            List<Integer> posterIds, int clubId, int uid) {
        logger.warn("uid:" + uid);
        //uid是俱乐部成员
        if (!clubMemberService.isClubMember(uid, clubId)) {
            return APIResponse.returnFail("你还不是这个俱乐部的小伙伴呀！");
        }
        //clubId+posterId联合搜索
        TbActivityPosterExample example = new TbActivityPosterExample();
        example.createCriteria().andIdIn(posterIds).andClubIdEqualTo(clubId);
        TbActivityPoster poster = new TbActivityPoster();
        poster.setIsDelete(Constants.BYTE_ONE);
        int count = tbActivityPosterMapper.updateByExampleSelective(poster, example);
        if (count <= 0) {
            return APIResponse.returnFail("啊呀，删除失败啦！");
        }
        return APIResponse.returnSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse cancelNotPayActivityOrder(Integer uid, Integer activityId,
                                                 String businessOrderNo) {
        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria()
                .andOrderUidEqualTo(uid).andActivityIdEqualTo(activityId)
                .andOrderNoEqualTo(businessOrderNo);
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);

        if (CollectionUtils.isEmpty(tbOrders)) {
            return APIResponse.returnFail("订单不存在");
        }

        TbOrder tbOrder = tbOrders.get(0);
        if (tbOrder.getOrderStatus().intValue() != 1) {

            return APIResponse.returnFail("不能取消订单");
        }

        TbSignUserExample signUserExample = new TbSignUserExample();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(tbOrder.getActivityId()) //活动id
                .andStatusEqualTo((int) Constants.BYTE_ONE)          //有效的
                .andOrderIdEqualTo(tbOrder.getId());
        List<TbSignUser> signUsers = signUserMapper.selectByExample(signUserExample);

        if (CollectionUtils.isEmpty(signUsers)) {
            return APIResponse.returnFail("订单不存在");
        }

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId());
        if (!activityAPIResponse.isRet()) {
            return activityAPIResponse;
        }
        RespClubActivity respClubActivity = activityAPIResponse.getData();
        if (!respClubActivity.getStatus().equals((byte) 0)) {
            return APIResponse.returnFail("活动已取消");
        }

        //恢复报名人数库存
        //计算要取消的男女报名人数
        int manCount = 0, femaleCount = 0;
        for (TbSignUser signUser : signUsers) {
            if (signUser.getGender() == Constants.BYTE_ONE) {
                manCount++;
            }
            if (signUser.getGender() == Constants.BYTE_TWO) {
                femaleCount++;
            }

        }
        logger.warn("count = " + signUsers.size());

        logger.warn("更新活动已报名人数，activityId:" + activityId);
        Map<String, Object> paraMap = Maps.newHashMap();
        //更新活动已经报名的有效人数
        try {
            paraMap.put("activityId", activityId);
            int minusCount = (0 - signUsers.size());
            if (minusCount > 0) {
                minusCount = 0;
            }
            //从活动报名人数库存中减去取消的男女人数
            APIResponse recoveryRes = recoverySignUpNum(
                    respClubActivity.getLimitNum(), tbOrder.getActivityId(), signUsers.size(), femaleCount, 0); //取消
            logger.warn("3 恢复报名人数库存，男：" + signUsers.size() + ", 女：" + femaleCount + ", 返回：" + JSON.toJSONString(recoveryRes));
            if (!recoveryRes.isRet()) {
                throw new BizException("恢复报名人库存异常：" + JSON.toJSONString(recoveryRes));
            }
            logger.warn("更新报名人数完成, minusCount" + minusCount);
        } catch (RpcException rpe) {
            throw new BizException("调用活动模块失败" + JSON.toJSONString(paraMap));
        }

        //4. 更新报名人报名记录表
        signUserExample.clear();
        signUserExample.createCriteria()
                .andActivityIdEqualTo(activityId)
                .andOrderIdEqualTo(tbOrder.getId());
        TbSignUser updateSignUser = new TbSignUser();
        updateSignUser.setIsCancel(1);//取消
        updateSignUser.setStatus(-1);//这里设置为下单超时未支付状态,现场管理成员列表中会去过滤掉超时未支付的.
        int uret = signUserMapper.updateByExampleSelective(updateSignUser, signUserExample);
        logger.warn("4 更新报名人报名记录表，更新为{}，返回：{}", JSON.toJSON(updateSignUser), uret);

        //如果有俱乐部余额抵扣 , 则退回
        if (tbOrder.getBalanceAmount() != null
                && tbOrder.getBalanceAmount().doubleValue() > 0) {
            ClubMemberAccountStreamInfo clubMemberAccountStreamInfo =
                    clubAccountService.addOrDeductionPersonClubAccountBalance(tbOrder.getBalanceAmount(),
                            tbOrder.getOrderUid(), respClubActivity.getClubId(), true);

            if (clubMemberAccountStreamInfo == null) {
                return APIResponse.returnFail("增加账户余额失败");
            }

            //type收支类型：0为充值，1为消费、2为退款
            TbClubOnlineMemberAccountStream tbClubOnlineMemberAccountStream
                    = clubAccountService.getPersonClubAccountStream(
                    tbOrder.getOrderUid(), respClubActivity.getClubId(),
                    respClubActivity.getActivityId(), 1);
            if (tbClubOnlineMemberAccountStream != null) {
                clubAccountService.deletePersonClubAccountStream(
                        tbClubOnlineMemberAccountStream.getId());
            }

            //记录个人账户流水
            //status 0:待处理 1：处理成功 2处理中 3：处理失败
            clubAccountService.recordPersonClubAccountDeductibleStream(
                    tbOrder.getOrderUid(),
                    tbOrder.getActivityId(),
                    respClubActivity.getName() + "报名费退款",
                    tbOrder.getPayType(), respClubActivity.getClubId(),
                    clubMemberAccountStreamInfo,
                    tbOrder.getOrderTradeNo(), (byte) 2, (byte) 2);
        }

        tbOrder.setCancelType((byte) 5);
        tbOrder.setOrderStatus((byte) 8);//设置成已取消
        orderMapper.updateByPrimaryKeySelective(tbOrder);

        //调用支付系统取消未支付订单
        APIRequest<ReqOrderCancel> apiRequest = new APIRequest<ReqOrderCancel>();
        ReqOrderCancel reqOrderCancel = new ReqOrderCancel();
        reqOrderCancel.setSourceSystemId(Constants.CLUB_SYSTEM_CODE);
        reqOrderCancel.setSourceBusinessId(
                Constants.CLUB_ACTIVITY_ORDER_BUSINESS_CODE);
        reqOrderCancel.setOrderNo(tbOrder.getOrderTradeNo());
        reqOrderCancel.setOutTradeNo(tbOrder.getOrderNo());
        reqOrderCancel.setUid(tbOrder.getOrderUid());
        reqOrderCancel.setCancelReason("订单超时未支付");
        apiRequest.setData(reqOrderCancel);
        APIResponse<BaseEnum> apiResponse = orderPayService.orderCancel(apiRequest);
        if (!apiResponse.isRet()) {
            throw new BizException("调用支付系统取消未支付订单失败：" + apiResponse.getErrmsg());
        }

        return APIResponse.returnSuccess();
    }

    @Override
    public PageObj<List<RespActivityPoster>> selectActivityPosterList(Integer pageNum, Integer pageSize, Integer categoryId, Integer clubId) {
        TbActivityPosterExample example = new TbActivityPosterExample();
        TbActivityPosterExample.Criteria criteria = example.createCriteria();
        Map<String, Object> map = new HashMap<String, Object>();
        criteria.andIsDeleteEqualTo(ClubConstants.IS_DELETE_FALSE);
        map.put("clubId", clubId);
        map.put("categoryId", categoryId);
        Limit limit = Limit.buildLimit(pageNum + 1, pageSize);
        map.put("limitStart", limit.getStart());
        map.put("limitSize", limit.getSize());
        logger.warn("Example:" + JSONObject.toJSONString(map));
        List<TbActivityPoster> posters = clubActivityMapper.selectActivityPostByClub(map);
        int total = clubActivityMapper.countActivityPostByClub(map);
        List<RespActivityPoster> response = new ArrayList<RespActivityPoster>();
        for (TbActivityPoster poster : posters) {
            RespActivityPoster resp = new RespActivityPoster();
            resp.setId(poster.getId());
            resp.setName(poster.getName());
            resp.setUrl(poster.getUrl());
            resp.setClubId(poster.getClubId());
            response.add(resp);
        }
        PageObj<List<RespActivityPoster>> result = PageObj.create(total, pageNum, pageSize, response);
        return result;
    }

    @Override
    public APIResponse<PageObj<List<ResActivityOrder>>> activityOrderList(
            Integer uid, Integer pageNum, Integer pageSize) {
        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andOrderUidEqualTo(uid);
        tbOrderExample.setOrderByClause(" id desc");
        tbOrderExample.setLimit(Limit.buildLimit(pageNum, pageSize));
        Integer total = orderMapper.countByExample(tbOrderExample);
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);

        List<ResActivityOrder> retList = Lists.newArrayList();

        Date curTime = new Date();
        for (TbOrder tbOrder : tbOrders) {
            APIResponse<RespClubActivity> activityAPIResponse =
                    queryClubActivityById(tbOrder.getActivityId());
            if (!activityAPIResponse.isRet()) {
                continue;
            }

            logger.warn("活动订单调测日志：" + JSONObject.toJSONString(tbOrder));
            ResActivityOrder resActivityOrder = new ResActivityOrder();
            TbSignUserExample signUserExample = new TbSignUserExample();
            signUserExample.createCriteria().andManageTypeEqualTo(4)
                    .andOrderIdEqualTo(tbOrder.getId())
                    .andActivityIdEqualTo(tbOrder.getActivityId())
                    .andIsCancelEqualTo(0).andStatusEqualTo(1);
            int signCount = signUserMapper.countByExample(signUserExample);
            if(signCount > 0)
            {
                resActivityOrder.setIsSign(1);
            }
            RespClubActivity respClubActivity = activityAPIResponse.getData();
            resActivityOrder.setRespClubActivity(respClubActivity);
            if (null != respClubActivity.getStartTime()) {
                resActivityOrder.setActivityStartTime(respClubActivity.getStartTime().getTime());
            }
            if (null != tbOrder.getCreateTime()) {
                resActivityOrder.setOrderCreateTime(tbOrder.getCreateTime().getTime());
            }
            resActivityOrder.setBusinessOrderNo(tbOrder.getOrderNo());
            if (null != tbOrder.getPayType()) {
                resActivityOrder.setPayId(tbOrder.getPayType().intValue());
            }
            resActivityOrder.setPayAmount(tbOrder.getPayAmount());
            resActivityOrder.setCurTime(curTime.getTime());

            if (curTime.getTime() < respClubActivity.getStartTime().getTime()) {
                resActivityOrder.setActivityStatus(1); //活动待开始
            } else if (curTime.getTime() > respClubActivity.getEndTime().getTime()) {
                resActivityOrder.setActivityStatus(2); //活动已经结束
            } else if ((curTime.getTime() >= respClubActivity.getStartTime().getTime())
                    && (curTime.getTime() < respClubActivity.getEndTime().getTime())) {
                resActivityOrder.setActivityStatus(3); //活动进行中
            }

            if (tbOrder.getCancelType().equals(Constants.BYTE_TWO)
                    || tbOrder.getCancelType().equals((byte) 3)
                    || tbOrder.getCancelType().equals((byte) 4)) {
                resActivityOrder.setActivityStatus(4); //活动已取消
            }

            //数据库订单状态: 0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消

            switch (tbOrder.getOrderStatus().intValue()) {
                case 0:
                case 8:
                    resActivityOrder.setOrderStatus(2); //订单已取消
                    break;
                case 1:
                case 3:
                    resActivityOrder.setOrderStatus(1); //订单待付款
                    break;
                case 2:
                    resActivityOrder.setOrderStatus(3); //订单已付款
                    if (curTime.getTime() > respClubActivity.getEndTime().getTime()) {
                        resActivityOrder.setOrderStatus(6); //订单已完成
                    }
                    break;
                case 4:
                    resActivityOrder.setOrderStatus(4); //订单退款中
                    break;
                case 5:
                    resActivityOrder.setOrderStatus(5); //订单已退款
                    break;
                case 6:
                    resActivityOrder.setOrderStatus(6); ///订单已完成
                    break;
                case 7:
                    resActivityOrder.setOrderStatus(7); //订单已评价
                    break;
                default:
                    break;
            }

//            ReqIsComment reqIsComment = new ReqIsComment();
//            reqIsComment.setUid(uid);
//            reqIsComment.setSystemCode(Constants.CLUB_SYSTEM_CODE);
//            reqIsComment.setBusinessCode(Constants.CLUB_ACTIVITY_COMMENT_BUSINESS_CODE);
//            reqIsComment.setBusinessId(respClubActivity.getActivityId());
//            APIResponse<Boolean> apiResponse = commentServiceFacade.checkIsComment(reqIsComment);
//            if (apiResponse.isRet() && apiResponse.getData()) {
//                resActivityOrder.setOrderStatus(7);//订单已评价
//            }

            retList.add(resActivityOrder);

        }

        PageObj<List<ResActivityOrder>> result = PageObj.create(total, pageNum, pageSize, retList);
        return APIResponse.returnSuccess(result);
    }


    @Async
    private void pushActivityUserCenterTaskMsg(int uid, Integer taskId) {
        UserTaskMsg userTaskMsg = new UserTaskMsg();
        userTaskMsg.setTaskId(taskId);
        userTaskMsg.setUid(uid);
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setTopic(Constants.MQ_TOPIC_TASK_TOPIC);
        mqRequestMsg.setTag(Constants.MQ_TOPIC_TASK_TAG);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(userTaskMsg));
        personCenterTaskClient.syncSend(mqRequestMsg);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse supplementLeaveRefundOrderCallBack(RefundNotifyMsg refundNotifyMsg) {
        TbOrderExample tbOrderExample = new TbOrderExample();
        tbOrderExample.createCriteria().andOrderStatusEqualTo((byte) 4)
                .andOrderNoEqualTo(refundNotifyMsg.getOutTradeNo());
        List<TbOrder> tbOrders = orderMapper.selectByExample(tbOrderExample);
        if (CollectionUtils.isEmpty(tbOrders)) {
            throw new BizException("补请假退款订单回调执行失败, 错误信息: 查询订单不存在, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo());
        }

        TbOrder tbOrder = tbOrders.get(0);
        OrderCallBackMsg orderCallBackMsg = new OrderCallBackMsg();
        orderCallBackMsg.setOrderNo(tbOrder.getOrderTradeNo());
        orderCallBackMsg.setType(OrderCallBackMsg.REFUND);

        APIResponse<RespClubActivity> activityAPIResponse =
                queryClubActivityById(tbOrder.getActivityId());
        if (!activityAPIResponse.isRet()) {
            orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("补请假退款订单回调执行失败, 错误信息: 调用dubbo查询活动信息失败, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo());
            throw new BizException("补请假退款订单回调执行失败, 错误信息: 调用dubbo查询活动信息失败, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo());
        }

        tbOrder.setOrderStatus((byte) 5);//设置成超时未支付
        int count = orderMapper.updateByPrimaryKeySelective(tbOrder);
        if (count <= 0) {
            orderCallBackMsg.setState((byte) 5);
            feedbackOrderSystemOrderStatus(orderCallBackMsg);
            logger.error("补请假退款订单回调执行失败, 更新订单状态失败, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo());
            throw new BizException("补请假退款订单回调执行失败, 更新订单状态失败, 业务订单号: "
                    + refundNotifyMsg.getOutTradeNo());
        }

        RespClubActivity respClubActivity = activityAPIResponse.getData();

        //如果有俱乐部余额抵扣 , 则退回
        if (tbOrder.getBalanceAmount() != null
                && tbOrder.getBalanceAmount().doubleValue() > 0) {
            ClubMemberAccountStreamInfo clubMemberAccountStreamInfo =
                    clubAccountService.addOrDeductionPersonClubAccountBalance(tbOrder.getBalanceAmount(),
                            tbOrder.getOrderUid(), respClubActivity.getClubId(), true);

            if (clubMemberAccountStreamInfo == null) {
                orderCallBackMsg.setState(OrderCallBackMsg.FAIL);
                feedbackOrderSystemOrderStatus(orderCallBackMsg);
                logger.error("补请假退款订单回调执行失败, 错误信息: 增加账户余额失败 业务订单号: "
                        + refundNotifyMsg.getOutTradeNo());
                throw new BizException("补请假退款订单回调执行失败, 错误信息: 增加账户余额失败 业务订单号: "
                        + refundNotifyMsg.getOutTradeNo());
            }
            TbClubOnlineMemberAccountStream tbClubOnlineMemberAccountStream
                    = clubAccountService.getPersonClubAccountStream(
                    tbOrder.getOrderUid(), respClubActivity.getClubId(),
                    respClubActivity.getActivityId(), 1);
            if (tbClubOnlineMemberAccountStream != null) {
                clubAccountService.deletePersonClubAccountStream(
                        tbClubOnlineMemberAccountStream.getId());
            }
            //记录个人账户流水
            clubAccountService.recordPersonClubAccountDeductibleStream(
                    tbOrder.getOrderUid(),
                    tbOrder.getActivityId(),
                    respClubActivity.getName() + "报名费退款",
                    tbOrder.getPayType(), respClubActivity.getClubId(),
                    clubMemberAccountStreamInfo,
                    tbOrder.getOrderTradeNo(), (byte) 2, (byte) 2);
        }

        orderCallBackMsg.setState(OrderCallBackMsg.SUCCESS);
        feedbackOrderSystemOrderStatus(orderCallBackMsg);

        return APIResponse.returnSuccess();
    }

}
